KVM (pseudovirtualiseeritud) VDI ĂŒhekordsete virtuaalsete masinatega bash'i abil

Kelle see artikkel on suunatud

See artikkel vĂ”ib huvi pakkuda sĂŒsteemiadministraatoritele, kellele on antud ĂŒlesanne luua â€žĂŒhekordsete” töökohtade teenus.

Proloog

Noore ja kiiresti areneva ettevĂ”tte IT-toe osakond pöördus palvega korraldada „ise teenindamise” punktid, mis oleksid kasutamiseks nende vĂ€listel klientidel. Need punktid pidi olema mĂ”eldud ettevĂ”tte vĂ€listele portaalidele registreerumiseks, andmete laadimiseks vĂ€liste seadmete kaudu ning riiklike portaalidega töötamiseks.

Oluline aspekt oli see, et suur osa tarkvarast on suunatud MS Windowsile (nĂ€iteks „Deklaratsioon”), ja hoolimata suundumustest avatud formaatide poole, jÀÀb MS Office domineerivaks standardiks elektrooniliste dokumentide vahetamisel. Seega ei saanud me sellest nĂ”udest lahkuda MS Windowsi kĂ”rvaldamisel.

Peamine probleem, mida nÀhti, oli vÔimalus koguda erinevaid kasutajaseansside andmeid, mis vÔivad viia nende lekkeni kolmandatele isikutele. Selline olukord on juba probleemiks saanud MFC-le.. Kuid erinevalt kvasi-riigiasutusest (riigi autonoomne asutus) MFЊ, saavad hindamatud organisatsioonid selle eest palju rangemaid karistusi. JÀrgmine kriitilisema probleemina tÔstatus nÔue töötada vÀliste andmehoidlatega, milles kahtlemata on hulgaliselt pahavara. Interneti kaudu pahavara sisseviimise tÔenÀosus peeti vÀhem tÔenÀoliseks, kuna interneti juurdepÀÀs on piiratult lubatud valge nimekiri aadressidest. NÔuete vÀljatöötamisele kaasati teiste osakondade töötajad, kes esitasid oma nÔuded ja soovid, ning lÔplikud nÔuded nÀgid vÀlja jÀrgmiselt:

IB nÔuded

  • PĂ€rast kasutamist peavad kĂ”ik kasutaja andmed (sealhulgas ajutised failid ja registervĂ”tmed) olema kustutatud.
  • KĂ”ik kasutaja poolt kĂ€ivitunud protsessid peavad töö lĂ”ppedes lĂ”petama.
  • Internetis juurdepÀÀs valge nimekiri aadressidest.
  • Piirangud kolmanda osapoole koodi kĂ€ivitamise vĂ”imalusele.
  • Kui sessioon jÀÀb seisma kauem kui 5 minutit, peab sessioon automaatselt lĂ”ppema ja jaam peab puhastuse tegema.

Kliendi nÔuded

  • Filiaali klienditeenindaja jaotus – maksimaalselt 4.
  • Minimaalne ooteaeg sĂŒsteemi valmimiseni, alates hetkest, kui 'istud toolile', kuni klientide tarkvara kasutamise alustamiseni.
  • VĂ”imalus ĂŒhendada perifeerseadmeid (skannerid, USB-mĂ€lud) otse 'isehooldusteenuse jaama' paigaldamiskohtadest.
  • Kliendi soovid
  • Reklaammaterjalide (piltide) demonstreerimine komplekside seiskamise ajal.

LoomehÀdad

PĂ€rast pikka mĂ€ngimist Windowsi livecd-idega oleme jĂ”udnud ĂŒksmeelsele jĂ€reldusele, et saadud lahendus ei rahulda vĂ€hemalt 3 kriitilist punkti. Need kas laadivad pikalt, ei ole tĂ”eliselt live, vĂ”i nende kohandamine oli seotud erakordsete probleemidega. VĂ”ib-olla otsisime halvasti ja te oskate soovitada mĂ”nda tööriistade komplekti, oleksin tĂ€nulik.

JĂ€tkusoone vaatamise asemel suundusime VDI suunas, kuid enamik lahendusi kas on liiga kallid vĂ”i vajavad suurt tĂ€helepanu. Soovisime lihtsat tööriista, millel on minimaalselt „maagiat”, ja enamiku probleemide lahendamine oleks vĂ”imalik lihtsalt teenuse taaskĂ€ivitamisega. Õnneks oli meil olemas serveritehnika, madalama klassi seadmed filiaalides, mille saime kasutada tehnoloogilise aluse loomiseks, mis oli saadud vananenud teenusest.

Mis lÔpuks vÀlja tuli? Kuidas lÔpuks lÀks, seda ma teile rÀÀkida ei saa, sest NDA, kuid otsingute kÀigus töötasime vÀlja huvitava skeemi, mis nÀitas laborikatsetes head tulemust, kuigi seeriatootmisse see ei lÀinud.

MĂ”ned tĂ€helepanekud: autor ei vĂ€ida, et pakutud lahendus lahendab tĂ€ielikult kĂ”ik esitatud ĂŒlesanded ja teeb seda vabatahtlikult ning lauldes. Autor nĂ”ustub eelnevalt vĂ€itega, et Sein Englishe sprache is zehr schlecht. Kuna lahendus enam ei arene, ei tasu loota bugide parandamisele vĂ”i funktsionaalsuse muutmisele, kĂ”ik on teie kĂ€tes. Autor eeldab, et teil on vĂ€hemalt vĂ€hegi teadmisi KVM-ist ja olete lugenud ĂŒlevaateartiklit Spice protokolli kohta ning veidi töötanud Centos vĂ”i mĂ”ne muu GNU Linuxi distributsiooniga.

Selles artiklis sooviksin analĂŒĂŒsida saavutatud lahenduse pĂ”hialuseid, nimelt kliendi ja serveri vahekorra ning virtuaalmasinate elu tsĂŒkli protsesside olemust seoses kĂ€sitletava lahendusega. Kui artikkel osutub publikule huvitavaks, kirjeldan live-piltide rakendamise ĂŒksikasju peenete klientide loomiseks Fedora pĂ”hjal ja rÀÀgin virtuaalmasinate seadmise detailidest. KVM server tĂ”hususe ja turvalisuse optimeerimiseks.

Kui vÔtta vÀrviline paber,
VĂ€rvid, pintslid ja liim,
Ja veel veidi osavust

Saab teha sada rubla!

Katse seadmise skeem ja kirjeldus

KVM (pseudovirtualiseeritud) VDI ĂŒhekordsete virtuaalsete masinatega bash'i abil

Kogu varustus asub filiaali vĂ”rgus, vĂ€ljapoole suundub ainult internetiĂŒhendus. Proxy-server on ajalooliselt juba olemas olnud, midagi erakordset ta endast ei esinda. Just sellel serveril toimub muu hulgas ka virtuaalmasinate (edasi teksis VMs) liikluse filtreerimine. Miski ei takista selle teenuse tootmist KVM-serveris, ainsana tuleb jĂ€lgida, kuidas see mĂ”ju avaldab diskialusele koormusele.

Client Station – meie teenuse „eneseabi“ ja „front-end“. Need on Lenovo IdeaCentre nettopsid. Miks on see seade hea? Peaaegu kĂ”iges, eriti rÔÔmustab suur USB-portide arv ja Kaardilugeja esipaneelil. Meie sĂŒsteemis on kaardilugejas SD kaart, millel on lubatud kirjutamise kaitse ja millele on salvestatud kohandatud live pilt Fedora 28. Muidugi on nettopsi kĂŒlge ĂŒhendatud ka monitor, klaviatuur ja hiir.

Switch – tĂ€iesti tavaline teise taseme riistvaraswitch, mis asub serveritoas ja vilgub valgustega. Ei ole ĂŒhendatud ĂŒkskĂ”ik milliste vĂ”rkudega peale „eneseabi“ jaamade.

KVM_Server – pĂ”hijoonis, mille testimisel Core 2 Quad Q9650 ja 8 GB RAM suudab tĂ”husalt töödelda kolm Windows 10 virtuaalmasinat. KĂ”vakettasĂŒsteem – adaptec 3405 kahel kettal Raid 1 + SSD. VĂ€likatsetel Xeon 1220 tĂ”sisem LSI 9260 + SSD suudab hĂ”lpsasti hallata 5-6 VM-i. Serverid saime me varisemise tagajĂ€rjel teenusest, kapitalikulud oleksid olnud minimaalsed. Sellel serveril (serveritel) on vĂ€lja töötatud KVM virtualiseerimissĂŒsteem koos virtuaalmasinate puulega pool_Vm.

VM – virtuaalmasin, meie teenuse taust. Siin toimub kasutaja töö.

Enp5s0 – vĂ”rgu liides, mis suhestub enese teenindamise „jaamade“ vĂ”rguga, kus resideeruvad dhcpd, ntpd, httpd ja xinetd kuulab „signaali“ porti.

Lo0 – pseudo-liides ringpöörde. Standardne.

Spice_console – VĂ€ga huvitav asi, fakt on selles, et erinevalt klassikalisest RDP-st, kui kĂ€ivitatakse KVM+Spice protokolli kombinatsioon, tekib tĂ€iendav element – virtuaalmasina konsoolipord. Ühendudes sellele TCP-pordile, saame me virtuaalmasina konsooli, ilma et oleks vaja ĂŒhendada virtuaalmasinaga lĂ€bi selle vĂ”rgu liidese. KĂ”ik interaktsioonid virtuaalmasinaga signaalide edastamise osas vĂ”tab server enda peale. lĂ€him sarnane funktsioon on IPKVM. See tĂ€hendab, et sellel pordil edastatakse virtuaalmasina monitori pilt, sellele saadetakse ka hiirekursori liikumise andmed ja (mis kĂ”ige tĂ€htsam) Spice protokolli kaudu on vĂ”imalik sujuvalt suunata USB seadmeid virtuaalmasinasse, justkui see seade oleks ĂŒhendatud ise virtuaalmasinaga. Kontrollitud flash-mĂ€lupulkade, skannerite ja veebikaameratega.

Vnet0, virbr0 ja virtuaalsed VM-i vÔrkaartid loovad virtuaalmasinate vÔrgu.

Kuidas SEE töötab

Kliendi jaama poolt

Kliendi tööjaam kĂ€ivitub graafilises reĆŸiimis modifitseeritud Fedora 28 live-pildilt, saab DHCP kaudu IP-aadressi aadressivahemikust 169.254.24.0/24. KĂ€ivitamise protsessis luuakse tulemĂŒĂŒri reeglid, mis vĂ”imaldavad ĂŒhendusi serveri «signal» ja «spice» portidele. PĂ€rast laadimist ootab tööjaam kasutaja «Client» autoriseerimist. PĂ€rast kasutaja autoriseerimist alustatakse töölaua halduri «openbox» kĂ€ivitamist ja autoriseeritud kasutaja nimel kĂ€ivitatakse autostardi skript autostart. Muuhulgas kĂ€ivitab autostardi skript skripti remote.sh.

$HOME/.config/openbox/scripts/remote.sh

#!/bin/sh

server_ip=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "server_ip" 
|/usr/bin/cut -d "=" -f2)
vdi_signal_port=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "vdi_signal_port" 
 |/usr/bin/cut -d "=" -f2)
vdi_spice_port=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "vdi_spice_port" 
|/usr/bin/cut -d "=" -f2)
animation_folder=$(/usr/bin/cat /etc/client.conf |/usr/bin/grep "animation_folder" 
|/usr/bin/cut -d "=" -f2)

process=/usr/bin/remote-viewer

while true
do
 if [ -z `/usr/bin/pidof feh` ]
 then
 /usr/bin/echo $animation_folder
 /usr/bin/feh -N -x -D1 $animation_folder &
 else
 /usr/bin/echo
 fi
/usr/bin/nc -i 1 $server_ip $vdi_signal_port |while read line
 do
  if /usr/bin/echo "$line" |/usr/bin/grep "RULE ADDED, CONNECT NOW!"
  then
   /usr/bin/killall feh
   pid_process=$($process "spice://$server_ip:$vdi_spice_port"  
   "--spice-disable-audio" "--spice-disable-effects=animation"  
   "--spice-preferred-compression=auto-glz" "-k" 
   "--kiosk-quit=on-disconnect" | /bin/echo $!)
   /usr/bin/wait $pid_process
   /usr/bin/killall -u $USER
   exit
  else
   /usr/bin/echo $line >> /var/log/remote.log
  fi
 done
done

/etc/client.conf

server_ip=169.254.24.1
vdi_signal_port=5905
vdi_spice_port=5906
animation_folder=/usr/share/backgrounds/animation
background_folder=/usr/share/backgrounds2/fedora-workstation

Muutujate kirjeldus failis client.conf
server_ip — KVM_Serveri aadress
vdi_signal_port — KVM_Serveri port, kus asub xinetd
vdi_spice_port — KVM_Serveri vĂ”rgupord, mille kaudu toimub remote-viewer kliendi ĂŒhendumise pĂ€ringu suunamine spetsiaalse VM spice porti (tĂ€iendavad ĂŒksikasjad allpool)
animation_folder — kaust, kust vĂ”etakse pilte bullshit animatsiooni nĂ€itamiseks
background_folder — kaust, kust saadetakse pilte esitluste ekraanil ootereĆŸiimis. Lisateave animatsiooni kohta artikli jĂ€rgmises osas.

Skript remote.sh vĂ”tab seaded failist konfiguratsioonist /etc/client.conf ja loob nc abil ĂŒhenduse KVM serveri „vdi_signal_port” sadamasse, saades serverilt andmevoo, milles oodatakse rea „RULE ADDED, CONNECT NOW”. Kui otsitud rida saabub, kĂ€ivitub kioskireĆŸiimis remote-viewer, luues ĂŒhenduse serveri „vdi_spice_port” sadamaga. Skripti tĂ€itmine peatatakse kuni remote-viewer'i tĂ€itmise lĂ”petamiseni.

Remote-viewer, ĂŒhendudes „vdi_spice_port” sadamasse, juhtimisredirekteerimise kaudu serveri pool, jĂ”uab lo0 liidese „spice_console” sadamasse, st virtuaalmasina konsooli ja toimub kasutaja töö. Ühenduse ootamise ajal nĂ€idatakse kasutajale bullshit animatsiooni, mis on slaidiasjade keeris jpeg failidest, pildi kaustateed mÀÀrab konfiguratsioonifaili muutuja animation_folder.

Kui ĂŒhendus 'spice_console' portiga kaob, mis nĂ€itab virtuaalmasina vĂ€ljalĂŒlitamist/taaskĂ€ivitamist (st kasutaja seansi tegelikku lĂ”ppu), lĂ”petatakse kĂ”ik autoriseeritud kasutaja nimel jooksnud protsessid, mis viib lightdm taaskĂ€ivitamiseni ja tagastab autoriseerimisekraanile.

KVM Serveri kĂŒljelt

‘signal’ port enp5s0 vĂ”rgukaardil ootab xinetd jaoks ĂŒhendust. PĂ€rast ĂŒhendust ‘signal’ port xinetd kĂ€ivitab skripti vm_manager.sh, edastamata sealjuures mingeid sisendparameetreid, ning suunab skripti vĂ€ljundi nc seanssi Client Station.

/etc/xinetd.d/test-server

service vdi_signal

{
port	=	5905
socket_type	=	stream
protocol	=	tcp
wait	=	no
user	=	root
server	=	/home/admin/scripts_vdi_new/vm_manager.sh
}

/home/admin/scripts_vdi_new/vm_manager.sh


#!/usr/bin/sh

#<SET LOCAL VARIABLES FOR SCRIPT>#
SRV_SCRIPTS_DIR=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_scripts_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR"
export SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR
SRV_POOL_SIZE=$(/usr/bin/cat /etc/vm_manager.conf 
|/usr/bin/grep "srv_pool_size" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_POOL_SIZE=$SRV_POOL_SIZE"
export "SRV_POOL_SIZE=$SRV_POOL_SIZE"
SRV_START_PORT_POOL=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_start_port_pool" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo SRV_START_PORT_POOL=$SRV_START_PORT_POOL
export SRV_START_PORT_POOL=$SRV_START_PORT_POOL
SRV_TMP_DIR=$(/usr/bin/cat /etc/vm_manager.conf 
|/usr/bin/grep "srv_tmp_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_TMP_DIR=$SRV_TMP_DIR"
export SRV_TMP_DIR=$SRV_TMP_DIR
date=$(/usr/bin/date)
#</SET LOCAL VARIABLES FOR SCRIPT>#

/usr/bin/echo "# $date START EXECUTE VM_MANAGER.SH #"

make_connect_to_vm() {

#<READING CLEAR.LIST AND CHECK PORT FOR NETWORK STATE>#
/usr/bin/echo "READING CLEAN.LIST AND CHECK PORT STATE"
#<CHECK FOR NO ONE PORT IN CLEAR.LIST>#

if [ -z `/usr/bin/cat $SRV_TMP_DIR/clear.list` ]
then
 /usr/bin/echo "NO AVALIBLE PORTS IN CLEAN.LIST FOUND"
 /usr/bin/echo "Will try to make housekeeper, and create new vm"
 make_housekeeper
else
 #<MINIMUN ONE PORT IN CLEAR.LIST FOUND>#
  /usr/bin/cat $SRV_TMP_DIR/clear.list |while read line
   do
    clear_vm_port=$(($line))
    /bin/echo "FOUND PORT $clear_vm_port IN CLEAN.LIST. TRY NETSTAT"  
    "CHECK FOR PORT=$clear_vm_port"

    #<NETSTAT LISTEN CHECK FOR PORT FROM CLEAN.LIST>#
    if /usr/bin/netstat -lnt |/usr/bin/grep ":$clear_vm_port" > /dev/null
     then
     /bin/echo "$clear_vm_port IS LISTEN"
     #<PORT IS LISTEN. CHECK FOR IS CONNECTED NOW>#
     if /usr/bin/netstat -nt |/usr/bin/grep ":$clear_vm_port"  
     |/usr/bin/grep "ESTABLISHED" > /dev/null
       then
#<PORT LISTEN AND ALREADY CONNECTED! MOVE PORT FROM CLEAR.LIST 
# TO WASTE.LIST>#
       /bin/echo "$clear_vm_port IS ALREADY CONNECTED, MOVE PORT TO WASTE.LIST"
       /usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
       /usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/waste.list
       else
#<PORT LISTEN AND NO ONE CONNECT NOW. MOVE PORT FROM CLEAR.LIST TO 
# CONN_WAIT.LIST AND CREATE IPTABLES RULES>##
       /usr/bin/echo "OK, $clear_vm_port IS NOT ALREADY CONNECTED"
       /usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
       /usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/conn_wait.list
       $SRV_SCRIPTS_DIR/vm_connect.sh $clear_vm_port
#<TRY TO CLEAN VM IN WASTE.LIST AND CREATE NEW WM>#
       /bin/echo "TRY TO CLEAN VM IN WASTE.LIST AND CREATE NEW VM"
       make_housekeeper
       /usr/bin/echo "# $date STOP EXECUTE VM_MANAGER.SH#"
       exit
       fi
     else
     #<PORT IS NOT A LISTEN. MOVE PORT FROM CLEAR.LIST TO WASTE.LIST>#
     /bin/echo " "$clear_vm_port" is NOT LISTEN. REMOVE PORT FROM CLEAR.LIST"
     /usr/bin/sed -i "/$clear_vm_port/d" $SRV_TMP_DIR/clear.list
     /usr/bin/echo $clear_vm_port >> $SRV_TMP_DIR/waste.list
    make_housekeeper
     fi
   done
fi
}

make_housekeeper() {
/usr/bin/echo "=Execute housekeeper="
/usr/bin/cat $SRV_TMP_DIR/waste.list |while read line
 do
 /usr/bin/echo "$line"
 if /usr/bin/netstat -lnt |/usr/bin/grep ":$line" > /dev/null
  then
  /bin/echo "port_alive, vm is running"
  if /usr/bin/netstat -nt |/usr/bin/grep ":$line"  
   |/usr/bin/grep "ESTABLISHED" > /dev/null
    then
    /bin/echo "port_in_use can't delete vm!!!"
    else
    /bin/echo "port_not in use. Deleting vm"
    /usr/bin/sed -i "/$line/d" $SRV_TMP_DIR/waste.list
    /usr/bin/echo $line >> $SRV_TMP_DIR/recycle.list
    $SRV_SCRIPTS_DIR/vm_delete.sh $line
    fi
  else
  /usr/bin/echo "posible vm is already off. Deleting vm"
  /usr/bin/echo "MOVE VM IN OFF STATE $line FROM WASTE.LIST TO"  
  "RECYCLE.LIST AND DELETE VM"
  /usr/bin/sed -i "/$line/d" $SRV_TMP_DIR/waste.list
  /usr/bin/echo $line >> $SRV_TMP_DIR/recycle.list
  $SRV_SCRIPTS_DIR/vm_delete.sh "$line"
 fi
done
create_clear_vm
}

create_clear_vm() {
/usr/bin/echo "=Create new VM="
while [ $SRV_POOL_SIZE -gt 0 ]
do
 new_vm_port=$(($SRV_START_PORT_POOL+$SRV_POOL_SIZE))
 /usr/bin/echo "new_vm_port=$new_vm_port"
 if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/clear.list > /dev/null
  then
  /usr/bin/echo "$new_vm_port port is already defined in clear.list"
  else
  if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/waste.list > /dev/null
   then
   /usr/bin/echo "$new_vm_port port is already defined in waste.list"
   else
    if /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/recycle.list > /dev/null
    then
    /usr/bin/echo "$new_vm_port PORT IS ALREADY DEFINED IN RECYCLE LIST"
    else
    if  /usr/bin/grep "$new_vm_port" $SRV_TMP_DIR/conn_wait.list > /dev/null
     then
     /usr/bin/echo "$new_vm_port PORT IS ALREADY DEFINED IN CONN_WAIT LIST"
     else
     /usr/bin/echo "PORT IN NOT DEFINED IN NO ONE LIST WILL CREATE" 
     "VM ON PORT $new_vm_port"
     /usr/bin/echo $new_vm_port >> $SRV_TMP_DIR/recycle.list
     $SRV_SCRIPTS_DIR/vm_create.sh $new_vm_port
     fi
    fi
   fi
 fi
 SRV_POOL_SIZE=$(($SRV_POOL_SIZE-1))
done
/usr/bin/echo "# $date STOP EXECUTE VM_MANAGER.SH #"
}
make_connect_to_vm |/usr/bin/tee -a /var/log/vm_manager.log

/etc/vm_manager.confsrv_scripts_dir=/home/admin/scripts_vdi_new
srv_pool_size=4
srv_start_port_pool=5920
srv_tmp_dir=/tmp/vm_state
base_host=win10_2
input_iface=enp5s0
vdi_spice_port=5906
count_conn_tryes=10

vm_manager.conf konfiguratsioonifaili muutujate kirjeldus
srv_scripts_dir — kaust, kus asuvad skriptid vm_manager.sh, vm_connect.sh, vm_delete.sh, vm_create.sh, vm_clear.sh
srv_pool_size — Vm-i puhuti suurus
srv_start_port_pool — algusport, millest alates hakkavad asuma virtuaalmasinate spice konsoolide portid
srv_tmp_dir — kaust ajutiste failide jaoks
base_host — pĂ”hivm (kuldne mudel), mille alusel luuakse Vm klone basseiniks
input_iface — serveri vĂ”rgu liides, mis suunab Klientjaamade poole
vdi_spice_port — serveri vĂ”rgupord, mille kaudu suunatakse remote-viewer kliendi ĂŒhendusipĂ€ring spice pordi suunatud Vm-ile
count_conn_tryes — ooteaeg, mille möödudes loetakse, et ĂŒhendust Vm-iga ei toimunud (tööpĂ”himĂ”tte kohta vaata vm_connect.sh)

Skript vm_manager.sh loeb konfiguratsioonifaili failist vm_manager.conf, hindab virtuaalmasinate olekut basseinist mitmete parameetrite alusel, nimelt: kui palju VM-e on juurutatud, kas on vabade puhaste VM-e. Selleks loeb ta faili clear.list, milles on „freshly created” (vt allpool VM-i loomise tsĂŒkkel) virtuaalmasinate „spice_console” portide numbrid, ning kontrollib nendele loodud ĂŒhenduse olemasolu. Kui leitakse port, millel on aktiivne vĂ”rguĂŒhendus (mida ei tohiks ilmtingimata juhtuda), antakse hoiatusteade ja port kantakse waste.list. Kui leiate esimese porta failist clear.list, millega hetkel pole ĂŒhendust, kutsub vm_manager.sh vĂ€lja skripti vm_connect.sh ja edastab sellele selle porta numbri parameetrina.

/home/admin/scripts_vdi_new/vm_connect.sh

#!/bin/sh

date=$(/usr/bin/date)

/usr/bin/echo "#" "$date" "START EXECUTE VM_CONNECT.SH#"

#<SET LOCAL VARIABLES FOR SCRIPT>#
free_port="$1"

input_iface=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep "input_iface" 
|/usr/bin/cut -d "=" -f2)
/usr/bin/echo "input_iface=$input_iface"

vdi_spice_port=$(/usr/bin/cat /etc/vm_manager.conf   
|/usr/bin/grep "vdi_spice_port" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "vdi_spice_port=$vdi_spice_port"

count_conn_tryes=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "count_conn_tryes" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "count_conn_tryes=$count_conn_tryes"
#</SET LOCAL VARIABLES FOR SCRIPT>#

#<CREATE IPTABLES RULES AND SEND SIGNAL TO CONNECT>#
/usr/bin/echo "create rule for port" $free_port
/usr/sbin/iptables -I INPUT -i $input_iface -p tcp -m tcp --dport  
$free_port  -j ACCEPT
/usr/sbin/iptables -I OUTPUT -o $input_iface -p tcp -m tcp --sport 
$free_port -j ACCEPT
/usr/sbin/iptables -t nat -I PREROUTING -p tcp -i $input_iface --dport  
$vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
/usr/bin/echo "RULE ADDED, CONNECT NOW!"
#</CREATE IPTABLES RULES AND SEND SIGNAL TO CONNECT>#

#<WAIT CONNECT ESTABLISHED AND ACTIVATE CONNECT TIMER>#
while [ $count_conn_tryes -gt 0 ]
do
if /usr/bin/netstat -nt |/usr/bin/grep ":$free_port"  
|/usr/bin/grep "ESTABLISHED" > /dev/null
 then
  /bin/echo "$free_port NOW in use!!!"
  /usr/bin/sleep 1s
  /usr/sbin/iptables -t nat -D PREROUTING -p tcp -i $input_iface --dport  
  $vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
  /usr/sbin/iptables -D INPUT -i $input_iface -p tcp -m tcp --dport  
  $free_port  -j ACCEPT
  /usr/sbin/iptables -D OUTPUT -o $input_iface -p tcp -m tcp --sport  
  $free_port -j ACCEPT
  /usr/bin/sed -i "/$free_port/d" $SRV_TMP_DIR/conn_wait.list
  /usr/bin/echo $free_port >> $SRV_TMP_DIR/waste.list
  return
 else
   /usr/bin/echo "$free_port NOT IN USE"
   /usr/bin/echo "RULE ADDED, CONNECT NOW!"
   /usr/bin/sleep 1s
 fi
count_conn_tryes=$((count_conn_tryes-1))
done
#</WAIT CONNECT ESTABLISED AND ACTIVATE CONNECT TIMER>#

#<IF COUNT HAS EXPIRED. REMOVE IPTABLES RULE AND REVERT 
# VM TO CLEAR.LIST>#
/usr/bin/echo "REVERT IPTABLES RULE AND REVERT VM TO CLEAN 
LIST $free_port"
/usr/sbin/iptables -t nat -D PREROUTING -p tcp -i $input_iface --dport 
$vdi_spice_port -j DNAT --to-destination 127.0.0.1:$free_port
/usr/sbin/iptables -D INPUT -i $input_iface -p tcp -m tcp --dport $free_port 
-j ACCEPT
/usr/sbin/iptables -D OUTPUT -o $input_iface -p tcp -m tcp --sport  
$free_port -j ACCEPT
/usr/bin/sed -i "/$free_port/d" $SRV_TMP_DIR/conn_wait.list
/usr/bin/echo $free_port >> $SRV_TMP_DIR/clear.list
#</COUNT HAS EXPIRED. REMOVE IPTABLES RULE AND REVERT VM 
#TO CLEAR.LIST>#
/usr/bin/echo "#" "$date" "END EXECUTE VM_CONNECT.SH#"

# Attention! Must Be!  sysctl net.ipv4.conf.all.route_localnet=1

Skript vm_connect.sh lisab tulemĂŒĂŒri reeglid, mis suunavad serveri enp5s0 liidese "vdi_spice_port" porti "spice console port" VM-ile, mis asub serveri lo0 liidesel ja edastatakse kĂ€ivitamisparameetrina. Port kantakse ĂŒle conn_wait.list'i, VM loetakse ĂŒhenduse ootamiseks. Client Stationi seansis edastatakse serveri "signal" pordile string "RULE ADDED, CONNECT NOW", mida ootab kĂ€ivitatud skript remote.sh. Algab ootetsĂŒkkel ĂŒhenduse loomisega, mille katsete arv mÀÀratakse konfiguratsioonifaili muutujaga "count_conn_tryes". Iga sekundi jĂ€rel edastatakse nc seansis string "RULE ADDED, CONNECT NOW" ja kontrollitakse, kas "spice_console" porti on ĂŒhendus loodud.

Kui ettenĂ€htud katsete arv on möödunud ja ĂŒhendust ei ole loodud, kantakse "spice_console" port tagasi clear.list'i. Skripti vm_connect.sh tĂ€itmine lĂ”petatakse ja jĂ€tkatakse vm_manager.sh tĂ€itmist, mis kĂ€ivitab puhastuskupli.

Kui kliendi jaama ĂŒhendust loetakse lo0 liidese "spice_console" pordiga, eemaldatakse tulemĂŒĂŒrireeglid, mis loovad ĂŒmbersuunamise serveri "spice" pordi ja "spice_console" pordi vahel, ning ĂŒhenduse sĂ€ilitamine toimub tulemĂŒĂŒri oleku mÀÀramise mehhanismi kaudu. Kui ĂŒhendus katke, ei saa uuesti "spice_console" pordiga ĂŒhendust luua. "Spice_console" port kantakse waste.list'i, VM peab olema "rĂ€pane" ja ta ei saa naasta "puhtasse" virtuaalmasinate basseinile ilma puhastusprotsessita. vm_connect.sh tĂ€itmine lĂ”peb, jĂ€tkub vm_manager.sh tĂ€itmine, mis kĂ€ivitab puhastusringi.

Puhastusprotsess algab failiga waste.list, kuhu kantakse virtuaalmasinate "spice_console" portide numbrid, millega on loodud ĂŒhendus. Kontrollitakse, kas iga "spice_console" porta suhtes on aktiivne ĂŒhendus. Kui ĂŒhendust ei ole, loetakse, et virtuaalmasinat ei kasutata enam, ning port kantakse recycle.list'i, ja kĂ€ivitatakse virtuaalmasina (vt allpool) kustamise protsess, millele see port kuulus. Kui tĂ”rget ei avastata ning port on aktiivne, peetakse virtuaalmasinat kasutatuks ning mingeid toiminguid tema suhtes ei tehta. Kui port ei kuule, loetakse, et VM on vĂ€lja lĂŒlitatud ja enam ei vajata. Port kantakse recycle.list'i ja kĂ€ivitatakse virtuaalmasina kustamise protsess. Selleks kĂ€ivitatakse skript vm_delete.sh, millele antakse parameetrina virtuaalmasina "spice_console" porti number, mille tuleb kustutada.

/home/admin/scripts_vdi_new/vm_delete.sh


#!/bin/sh

#<Set local VARIABLES>#
port_to_delete="$1"
date=$(/usr/bin/date)
#</Set local VARIABLES>#

/usr/bin/echo "# $date START EXECUTE VM_DELETE.SH#"
/usr/bin/echo "TRY DELETE VM ON PORT: $vm_port"

#<VM NAME SETUP>#
vm_name_part1=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep 'base_host' 
|/usr/bin/cut -d'=' -f2)
vm_name=$(/usr/bin/echo "$vm_name_part1""-""$port_to_delete")
#</VM NAME SETUP>#

#<SHUTDOWN AND DELETE VM>#
/usr/bin/virsh destroy $vm_name
/usr/bin/virsh undefine $vm_name
/usr/bin/rm -f /var/lib/libvirt/images_write/$vm_name.qcow2
/usr/bin/sed -i "/$port_to_delete/d" $SRV_TMP_DIR/recycle.list
#</SHUTDOWN AND DELETE VM>#

/usr/bin/echo "VM ON PORT $vm_port HAS BEEN DELETE AND REMOVE" 
 "FROM RECYCLE.LIST. EXIT FROM VM_DELETE.SH"
/usr/bin/echo "# $date STOP EXECUTE VM_DELETE.SH#"
exit

Virtuaalse masina eemaldamine on piisavalt lihtne toiming, skript vm_delete.sh tuvastab virtuaalse masina nime, mille port on antud kĂ€ivitamisparameetrina. Teostatakse VM-a sundseisak, eemaldatakse VM hĂŒperviisorist ja kustutatakse selle virtuaalne kĂ”vaketas. Port "spice_console" eemaldatakse recycle.listist. Skripti vm_delete.sh tĂ€itmine lĂ”ppeb ning jĂ€tkub vm_manager.sh tĂ€itmine.

Skripti vm_manager.sh lĂ”ppedes, pĂ€rast tarbetute virtuaalsete masinate eemaldamise toimingute lĂ”puleviimist waste.listist, alustab see virtuaalsete masinate loomise tsĂŒklit basseinist.

Protsess algab selle mÀÀratlemisega, millised "spice_console" sadamad on saadaval. Selleks, lÀhtudes konfiguratsioonifaili parameetrist "srv_start_port_pool", mis mÀÀrab algsadama virtuaalmasinate "spice_console" basseinis, ja parameetrist "srv_pool_size", mis mÀÀrab maksimaalse virtuaalmasinate arvu, toimub kÔikide sadamate jÀrjestikune kontrollimine. Iga mÀÀratletud sadama puhul otsitakse seda failidest clear.list, waste.list, conn_wait.list, recycle.list. Kui sadam leitakse mÔnes neist failidest, loetakse sadam hÔivatuks ja jÀetakse vahele. Kui sadamat nimetatud failides ei leita, lisatakse see faili recycle.list ja algab uue virtuaalmasina loomise protsess. Selleks kutsutakse vÀlja skript vm_create.sh, millele edastatakse parameetri "spice_console" sadama number, mille jaoks tuleb VM luua.

/home/admin/scripts_vdi_new/vm_create.sh


#!/bin/sh
/usr/bin/echo "#" "$date" "START RUNNING VM_CREATE.SH#"

new_vm_port=$1
date=$(/usr/bin/date)
a=0
/usr/bin/echo SRV_TMP_DIR=$SRV_TMP_DIR

#<SET LOCAL VARIABLES FOR SCRIPT>#
base_host=$(/usr/bin/cat /etc/vm_manager.conf |/usr/bin/grep "base_host" 
|/usr/bin/cut -d "=" -f2)
/usr/bin/echo "base_host=$base_host"
#</SET LOCAL VARIABLES FOR SCRIPT>#

hdd_image_locate() {

/bin/echo "Run STEP 1 - hdd_image_locate"

hdd_base_image=$(/usr/bin/virsh dumpxml $base_host  
|/usr/bin/grep "source file" |/usr/bin/grep "qcow2" |/usr/bin/head -n 1 
|/usr/bin/cut -d "'" -f2)
if [ -z "$hdd_base_image" ]
then
 /bin/echo "base hdd image not found!"
else
 /usr/bin/echo "hdd_base_image found is a $hdd_base_image. Run next step 2"

#< CHECK FOR SNAPSHOT ON BASE HDD >#

  if [ 0 -eq `/usr/bin/qemu-img info "$hdd_base_image" | /usr/bin/grep -c "Snapshot"` ]
  then
  /usr/bin/echo "base image haven't snapshot, run NEXT STEP 3"
  else
  /usr/bin/echo "base hdd image have a snapshot, can't use this image"
  exit
  fi
#</ CHECK FOR SNAPSHOT ON BASE HDD >#

#< CHECK FOR HDD IMAGE IS LINK CLONE >#
  if [ 0 -eq `/usr/bin/qemu-img info "$hdd_base_image" |/usr/bin/grep -c "backing file"
  then
  /usr/bin/echo "base image is not a linked clone, NEXT STEP 4"
  /usr/bin/echo "Base image check complete!"
  else
  /usr/bin/echo "base hdd image is a linked clone, can't use this image"
  exit
  fi
fi
#</ CHECK FOR HDD IMAGE IS LINK CLONE >#
cloning
    }

cloning() {
# <Step_1 turn the base VM off >#
 /usr/bin/virsh shutdown $base_host > /dev/null 2>&1
 # </Step_1 turn the base VM off >#

#<Create_vm_config>#

/usr/bin/echo "Free port for Spice VM is $new_vm_port"

 #<Setup_name_for_new_VM>#
new_vm_name=$(/bin/echo $base_host"-"$new_vm_port)
#</Setup_name_for_new_VM>#

#<Make_base_config_as_clone_base_VM>#
/usr/bin/virsh dumpxml $base_host > $SRV_TMP_DIR/$new_vm_name.xml
#<Make_base_config_as_clone_base_VM>#

##<Setup_New_VM_Name_in_config>##
/usr/bin/sed -i "s%<name>$base_host</name>%<name>$new_vm_name</name>%g" $SRV_TMP_DIR/$new_vm_name.xml
#</Setup_New_VM_Name_in_config>#

#<UUID Changing>#
old_uuid=$(/usr/bin/cat $SRV_TMP_DIR/$new_vm_name.xml |/usr/bin/grep "<uuid>")
/usr/bin/echo old UUID $old_uuid
new_uuid_part1=$(/usr/bin/echo "$old_uuid" |/usr/bin/cut -d "-" -f 1,2)
new_uuid_part2=$(/usr/bin/echo "$old_uuid" |/usr/bin/cut -d "-" -f 4,5)
new_uuid=$(/bin/echo $new_uuid_part1"-"$new_vm_port"-"$new_uuid_part2)
/usr/bin/echo $new_uuid
/usr/bin/sed -i "s%$old_uuid%$new_uuid%g" $SRV_TMP_DIR/$new_vm_name.xml
#</UUID Changing>#


#<Spice port replace>#
old_spice_port=$(/usr/bin/cat  $SRV_TMP_DIR/$new_vm_name.xml  
|/usr/bin/grep "graphics type='spice' port=")
/bin/echo old spice port $old_spice_port
new_spice_port=$(/usr/bin/echo "<graphics type='spice' port='$new_vm_port' autoport='no' listen='127.0.0.1'>")
/bin/echo $new_spice_port
/usr/bin/sed -i "s%$old_spice_port%$new_spice_port%g" $SRV_TMP_DIR/$new_vm_name.xml
#</Spice port replace>#

#<MAC_ADDR_GENERATE>#
mac_new=$(/usr/bin/hexdump -n6 -e '/1 ":%02X"' /dev/random|/usr/bin/sed s/^://g)
/usr/bin/echo New Mac is $mac_new
#</MAC_ADDR_GENERATE>#

#<GET OLD MAC AND REPLACE>#
mac_old=$(/usr/bin/cat $SRV_TMP_DIR/$new_vm_name.xml |/usr/bin/grep "mac address=")
/usr/bin/echo old mac is $mac_old
/usr/bin/sed -i "s%$mac_old%$mac_new%g" $SRV_TMP_DIR/$new_vm_name.xml
#<GET OLD MAC AND REPLACE>#

#<new_disk_create>#
/usr/bin/qemu-img create -f qcow2 -b $hdd_base_image /var/lib/libvirt/images_write/$new_vm_name.qcow2
#</new_disk_create>#

#<attach_new_disk_in_confiig>#
/usr/bin/echo hdd base image is $hdd_base_image
/usr/bin/sed -i "s%<source file='$hdd_base_image'/>%<source file='/var/lib/libvirt/images_write/$new_vm_name.qcow2'/>%g" $SRV_TMP_DIR/$new_vm_name.xml
#</attach_new_disk_in_confiig>#

starting_vm
    #</Create_vm config>#
}

starting_vm() {

/usr/bin/virsh define $SRV_TMP_DIR/$new_vm_name.xml
/usr/bin/virsh start $new_vm_name
while [ $a -ne 1 ]
do
if /usr/bin/virsh list --all |/usr/bin/grep "$new_vm_name" |/usr/bin/grep "running" > /dev/null 2>&1
then
a=1
/usr/bin/sed -i "/$new_vm_port/d" $SRV_TMP_DIR/recycle.list
/usr/bin/echo $new_vm_port >> $SRV_TMP_DIR/clear.list
/usr/bin/echo "#" "$date" "VM $new_vm_name IS STARTED #"
else
 /usr/bin/echo "#VM $new_vm_name is not ready#"
a=0
/usr/bin/sleep 2s
fi
done
/usr/bin/echo "#$date  EXIT FROM VM_CREATE.SH#"
exit
}

hdd_image_locate

Uue virtuaalmasina loomise protsess

Skript vm_create.sh loeb konfiguratsioonifailist muutuja «base_host» vÀÀrtuse, mis mÀÀratleb virtuaalmasina malli, mille pÔhjal luuakse kloon. See tÔmbab vÀlja VM-i XML-konfiguratsiooni hypervisorist, teeb mitmeid kontrolli QCOW ketta pildi kohta ja, kui need on edukad, loob uue VM-i XML-konfiguratsioonifaili ja «linked clone» ketta pildi uuele VM-ile. PÀrast seda laaditakse uue VM-i XML-konfiguratsioon hypervisorisse ja VM kÀivitatakse. Port «spice_console» kantakse recycle.list failist clear.list faili. vm_create.sh tÀitmine lÔppeb ja vm_manager.sh tÀitmine lÔpetatakse.
JĂ€rgmise ĂŒhenduse korral algab kĂ”ik algusest.

HĂ€daolukordade jaoks on komplektis skript vm_clear.sh, mis sundkorras lĂ€bib kĂ”ik VM-id grupis ja kustutab need, nullides listide vÀÀrtused. Selle kutsumine laadimise etapis vĂ”imaldab (ĂŒhe)VDI-d alustada puhtalt lehelt.

/home/admin/scripts_vdi_new/vm_clear.sh

#!/usr/bin/sh

#set VARIABLES#
SRV_SCRIPTS_DIR=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_scripts_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR"
export SRV_SCRIPTS_DIR=$SRV_SCRIPTS_DIR

SRV_TMP_DIR=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_tmp_dir" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_TMP_DIR=$SRV_TMP_DIR"
export SRV_TMP_DIR=$SRV_TMP_DIR

SRV_POOL_SIZE=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_pool_size" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo "SRV_POOL_SIZE=$SRV_POOL_SIZE"

SRV_START_PORT_POOL=$(/usr/bin/cat /etc/vm_manager.conf  
|/usr/bin/grep "srv_start_port_pool" |/usr/bin/cut -d "=" -f2)
/usr/bin/echo SRV_START_PORT_POOL=$SRV_START_PORT_POOL
#Set VARIABLES#


/usr/bin/echo "= Cleanup ALL VM="

/usr/bin/mkdir $SRV_TMP_DIR

/usr/sbin/service iptables restart
/usr/bin/cat /dev/null > $SRV_TMP_DIR/clear.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/waste.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/recycle.list
/usr/bin/cat /dev/null > $SRV_TMP_DIR/conn_wait.list

port_to_delete=$(($SRV_START_PORT_POOL+$SRV_POOL_SIZE))

        while [ "$port_to_delete" -gt "$SRV_START_PORT_POOL" ]
          do
		$SRV_SCRIPTS_DIR/vm_delete.sh $port_to_delete
		port_to_delete=$(($port_to_delete-1))
        done

/usr/bin/echo "= EXIT FROM VM_CLEAR.SH="

Sellega lĂ”petan oma jutu esimese osa. Esitatud teave peaks olema piisav, et sĂŒsteemiadministraatorid saaksid proovida (under)VDI-t praktikas. Kui kogukond leiab selle teema huvitavana, tutvustan teises osas Fedora livecd modifikatsiooni ja selle muutmist kiosksĂŒsteemiks.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster