VTiger CRM telepítése (Wheezy)

Innen: AdminWiki

Ebben a leírásban a vTiger CRM ügyfélkapcsolati webalkalmazás open source változatának telepítését és üzemeltetését tárgyaljuk házirend szerint telepített Debian Wheezy (wsm2) LAMP szerveren.

Ez a leírás a vTiger 5.4.0-ra vonatkozik, a 6.x "hamarosan érkezik" és jelentősen át lesz írva (vTiger blog 2013-06: "We’ve changed the code-base of Vtiger to follow an MVC model [...]"). Talán érdemes production használattal a 6.x verziót megvárni.

A CRM szoftver definíciója a Wikipédián - "Az ügyfélkapcsolat-kezelés (Customer Relationship Management - CRM) fogalma egy cég partnerei felé irányuló folyamatainak leírására vonatkozik. A CRM szoftver célja, hogy ezeket a folyamatokat támogassa, illetve hogy jelenlegi és potenciális ügyfelekkel kapcsolatos információkat tároljon."

MÉG NE VEDD KOMOLYAN!

Elméleti megfontolások

Hasonlóan más LAMP webalkalmazásokhoz, a vTigert is úgy kívánjuk üzemeltetni, hogy:

  • ne igényeljen dedikált gépet, egy szervergépen - más-más Apache virtualhostok alatt - több példány (instance) is működjön;
  • minden példány önálló, dedikált tárterületet és MySQL adatbázist használjon.

Tekintettel arra, hogy az alkalmazás bizalmas adatokat kezel:

  • érdemes azt csak titkosított (HTTPs) protokollon elérhetővé tenni;
  • esetleg a nagyközönség elől elzárni (de nem a triviális, viszont a távmunkát megnehezítő IP szűréssel! - TODO!).

Sajnos az alkalmazással kapcsolatban néhány, nem jelentéktelen biztonsági probléma merül fel:

  • Az alkalmazást nem úgy tervezték, hogy a kódkészlet és az adatterület megfelelően elkülöníthető legyen (számos beégetett dirname(__FILE__) path, pluginek telepítése saját web interface-én keresztül, azaz az írható és futtatható tárterület nem elkülöníthető, stb.), így az egész alkalmazást a számára dedikált virtualhost web tárterületén kell futtatnunk (nem lehet R/O közös kódkészlet), és itt "majdnem mindenre" írásjogot kell adni (TODO!);
  • A felhasználói felületről érkező adatok szanitizációja hiányos, és ezek az adatokban rendeltetésszerű használat közben is "bármi lehet", így a ModSecurity-vel sem szűrhetőek értelmesen;
  • A kódkészlet elavult, a Debian Wheezy-ben szereplő PHP 5.4.x-ben már nem szereplő utasításokat és eljárásokat tartalmaz (patchelés nélkül jelenleg nem is működőképes);
  • Barátságtalan a vTiger programfrissítési módszere: a fejlesztők elképzelése szerint az új verziót egy másik adatterületen kell üzembe helyezni, és a régebbi verzió adattartalmát ide migrálni (TODO!).

Nézetem szerint az alkalmazás lényeges, "by design" (tervezésből fakadó, üzemeltetéssel könnyen nem ellensúlyozható) biztonsági problémákkal küzd, virtuális környezetbe zárása megfontolandó (TODO!).

Előfeltételek

  • Apache 2.x + wsm2 (Debian csomagból, illetve házirend szerint telepítve)
  • MySQL 5.x (Debian csomagból házirend szerint telepítve)

A vTiger MySQL InnoDB táblákat használ, ezért az InnoDB engine-t engedélyezni kell (a házirend szerint így van).

  • PHP 5.x (Debian csomagból házirend szerint telepítve)

Szükség van a PHP GD, IMAP, opcionálisan CURL moduljaira és opcionálisan az OpenSSL-re (ha még nem lennének telepítve):

apt-get install php5-gd php5-imap  # Kötelező
apt-get install php5-curl openssl  # Opcionális

A PHP beállításoknál a levélküldésre, sajnos az ini_set-re és az include-ra szükség van:

-rw-r--r-- root root /etc/php5/apache2/conf.d/wsm2-php5.ini

[...]
disable_functions = [...]; mail, ini_set, include
[...]

Megjegyzés: a beállítások érvényesítéséhez a webszerverek konfigurációit újra kellene olvastatni, de ezt elhagyhatjuk, mert később a wsm2 úgyis megteszi.

  • A kódkészlet szükség szerinti patcheléséhez a patch segédprogram is szükséges:
apt-get install patch  # Nincs lényeges függősége
  • TODO!

Telepítés

Egy vTiger példányhoz tartozik egy dedikált MySQL adatbázis, egy Apache virtualhost tárterülettel és webszerver (alkalmazásszerver) beállításokkal, valamint a vTiger saját beállítása (melyeket a telepítője inicializál).

MySQL adatbázis készítése

A MySQL adatbázisnak egyetlen, az adatbázisra nézve teljes jogú felhasználója van, akinek neve célszerűen megegyezik az adatbázis nevével. A nevet konvencionálisan vt_-vel kezdjük, és célszerű, ha kapcsolatban áll a virtualhost nevével.

Az adatbázist és a felhasználót a MySQL root hozzáféréssel hozzuk létre.

mysql --defaults-file=/etc/mysql/root.cnf

mysql> CREATE DATABASE vt_INSTANCENAME CHARACTER SET utf8 DEFAULT COLLATE utf8_hungarian_ci;
mysql> GRANT ALL PRIVILEGES ON vt_INSTANCENAME.* TO 'vt_INSTANCENAME'@'localhost' IDENTIFIED BY 'PASSWORD';
mysql> FLUSH PRIVILEGES;

ahol a PASSWORD egy megfelelő jelszó. Relatív megjegyezhető, mégis erős jelszó a pwgen segédprogrammal is generálható, pl. a következőképpen:

/usr/bin/pwgen -s -n -c 12 1

Ellenőrizzük, hogy a felhasználó megfelelően létrejött-e:

mysql> SELECT host, user, password FROM mysql.user ORDER BY user;
+-----------+------------------+---------------------------------------------+
| host      | user             | password                                    |
+-----------+------------------+---------------------------------------------+
| localhost | vt_INSTANCENAME  | *73CDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
[...]

mysql> quit

Ezután próbáljunk a létrehozott felhasználó nevében és jelszavával belépni. Az alábbi parancsokkal ellenőrizhetjük, hogy a felhasználó jogosultságai valóban csak erre az adatbázisra terjednek ki:

mysql -u oc_INSTANCENAME -p
Enter password:

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| oc_INSTANCENAME    |
+--------------------+

A felhasználó felvételét és kipróbálását követően töröljük le a .mysql_history állományt, mert ebben a jelszó szabad szöveges formában benne van:

rm ~/.mysql_history

Az adatbázis iniciális feltöltését a telepítő PHP script végzi.

Apache virtualhost készítése

Leírásunkban a http://fully.qualified.hostname weboldal közvetlenül a vTiger példány nyitólapjára mutat. A virtualhostot a szokott módon, a wsm2 segítségével készítjük el:

wsm2 -cw FULLY.QUALIFIED.HOSTNAME sysadmin@MYDOMAIN

Filerendszer beállítások

A wsm által létrehozott állományokat a bin, log könyvtár és az awstats link kivételével töröljük:

cd /var/www/[FQHN]
rm -R  `ls -1 | grep -iv awstats | grep -iv bin | grep -iv log`

Szerezzük be a telepítőkészletet (ügyeljünk arra, hogy a forrást - source, tar.gz -, és ne a bináris telepítőt töltsük le!), és tömörítsük ki a /var/www/[FQHN] útvonalra (a vtigercrm alkönyvtár mellőzésével, azaz úgy, hogy a /var/www/[FQHN]/index.php létezzen) - ezután a telepítőkészletre már nincs szükség, archiválható vagy törölhető.

A kódkészlet patchelése

v5.4.0 bugfix: sajnos a vTiger 5.4.0 verziójának kódja jelenleg nem kompatibilis a Debian Wheezy-ben lévő PHP 5.4+ verziójával (erősen elavult, illetve PHP fatal error-t okozó kódrészleteket tartalmaz), így kénytelenek vagyunk patchelni. Töltsünk le egy erre a célra szolgáló, közösségi fejlesztésű patch állományt, pl. a /root/tmp ideiglenes könyvtárba, és alkalmazzuk:

pwd                                                   # /var/www/[FQHN] legyen!
patch -p1 </root/tmp/vtigercrm-5.4.0-PHPv54-v2.patch  # Ellenőrizzük a nevét!

A patch file tartalmaz néhány, alapértelmezésben nem telepített állományra vonatkozó patchet, ezeket egyelőre lépjük át (File to patch: - enter, Skip this patch? [y] - enter).

Tulajdonviszonyok és jogosultságok beállítása

A kitömörítés és patch után a kódállományok tulajdonlása és jogai a csomag készítőjének beállításait tartalmazzák. Állítsuk be a mi házirendünk szerinti tulajdonviszonyokat és jogokat:

  • alapértelmezés: tulajdonos webadmin:www-data, könyvtárakra 2750, fájlokra 640
  • a PHP által írható állományokra (részletezést ld. a vTiger Wikiben): tulajdonos webadmin:www-data, könyvtárakra 2770 setfacl -d -m g::rwX, fájlokra 660
pwd # /var/www/[FQHN] legyen!

# alapértelmezések beállítása
find . -type d -exec chown webadmin:www-data {} \; -exec chmod 2750 {} \;
find . -type f -exec chown webadmin:www-data {} \; -exec chmod  640 {} \;
find . -type l -exec chown -h webadmin:www-data {} \; # csak szépség

# www-data által írható könyvtárak (rekurzív, a benne lévő fájlok is)
folderlist="Smarty/cache backup cache logs modules/Emails/templates modules/Webmails/tmp storage test"
for folder in $folderlist; do find $folder -type d -exec chmod 2770 {} \; -exec setfacl -d -m g::rwX {} \;; done
for folder in $folderlist; do find $folder -type f -exec chmod  660 {} \;; done

# www-data által írható könyvtárak (explicit, csak a megadott könyvtár)
folderlist="Smarty/templates_c Smarty/templates/modules cron/modules include/js install modules user_privileges"
for folder in $folderlist;  do chmod 2770 $folder; setfacl -d -m g::rwX $folder; done

# www-data által írható nyelvi könyvtárak
find . -name language -type d -exec chmod 2770 {} \; -exec setfacl -d -m g::rwX {} \;

# www-data által írható fájlok (explicit, csak a megadott fájl)
filelist="config.inc.php tabdata.php install.php parent_tabdata.php"
for file in $filelist; do chmod 660 $file; done

Apache beállítások

A virtualhost wsm2 által létrehozott konfigurációjában:

  • beállítjuk az esetleges ServerAlias-okat;
  • engedélyezzük a PHP futtatást és upload-ot, beállítjuk a temp könyvtárat, módosítjuk a memory_limit-et, megnöveljük a végrehajtási időt;
  • noha a vTiger Wiki kifejezetten kéri, nem kell engedélyezzük az elavult allow_call_time_pass_reference és az alapértelmezetten bekapcsolt short_open_tag PHP direktívákat;
  • sajnos a vTiger forgalmat a mod_security értelmesen szűrni nem tudja, ezért - jobb híján - kikapcsoljuk az ellenőrzést (TODO!);
  • engedélyezzük a symlinkeket;
  • az írható könyvtárakban igyekszünk tiltani a HTML értelmezést és a PHP futtatást;
  • korlátozzuk a hozzáférést bizonyos fájltípusokhoz és (a telepítés lefuttatása után) a telepítőprogramhoz;
  • töröljük a nem használt könyvtárakra (config, download, upload) vonatkozó bejegyzéseket;
  • TODO!
-rw-r--r-- root root /etc/apache2/sites-enabled/[FQHN]

[...]
    <IfModule mod_php5.c>
        php_admin_flag engine on
        [...]
        php_admin_value memory_limit 64M
        php_admin_value max_execution_time 600
        [...]
        php_admin_flag file_uploads on
#       php_admin_flag apc.rfc1867 on
        php_admin_value upload_max_filesize 10M
        php_admin_value post_max_size 10M
        php_admin_value upload_tmp_dir /var/www/FQHN/cache/upload/
        [...]
    </IfModule>

[...]
    # ModSecurity settings (entire virtualhost).
    <IfModule security2_module>
        # Engine On/Off/DetectionOnly.
        SecRuleEngine off
        [...]
    </IfModule>

[...]
    <Directory /var/www/FQHN>
        [...]
        Options +FollowSymLinks
#       Options +SymLinksIfOwnerMatch
    </Directory>

[...]
    # Protected folders
    <LocationMatch "^/(cache)|(storage)">
        Allow from all
        AddType text/plain .html .htm .shtml
        Options -FollowSymLinks
        Options -SymLinksIfOwnerMatch
        # PHP disabled here.
        <IfModule mod_php4.c>
            php_admin_flag engine off
        </IfModule>
        <IfModule mod_php5.c>
            php_admin_flag engine off
        </IfModule>
        # ModSecurity disabled here.
        <IfModule security2_module>
            SecRuleEngine Off
        </IfModule>
    </LocationMatch>

    # Protected file types
    <FilesMatch "\.(txt)$">
        Order deny,allow
        Deny from all
    </FilesMatch>
    <FilesMatch "robots.txt">
        Order deny,allow
        Allow from all
    </FilesMatch>

    # Disable installer
    <LocationMatch "^/(install)|(install.php)">
        Order deny,allow
#       Deny from all
    </LocationMatch>
[...]

A változtatásokat a webszerver konfiguráció újraolvastatásával érvényesíthetjük:

/etc/init.d/apache2 reload

Telepítőprogram futtatása

A webszerver konfiguráció újraolvastatása után, lehetőleg azonnal egy, a telepítés alatt álló szervert HTTP protokollon keresztül elérő munkaállomás grafikus böngészőjében kérjük el a http://FQHN/ weblapot, amelyik a telepítőprogram (angol nyelvű) webfelületére visz:

  • szűz telepítést (Install) kérjünk, ne frissítést (Migrate);
  • fogadjuk el a licence-et;
  • a telepítés előtti ellenőrzésnél (Pre-Installation Check) a kötelezőek (bal felső mező) és az írásjogok (Read/Write Access) legyenek rendben (jobb oldalon ne legyen panaszkodás - enélkül a telepítő nem is enged tovább), az ajánlásokkal (Recommended PHP Settings) most ne törődjünk, az ellenőrző kérdésre (Some of the PHP Settings do not meet the recommended values. This might affect some of the features of vtiger CRM. Are you sure, you want to proceed?) ezt erősítsük meg;
  • adjuk meg a korábban létrehozott adatbázis adatait (a hostnév localhost legyen!), ne kérjünk demo adatokat (Populate database with demo data ne legyen kipipálva), az URL-ben https://FQHN szerepeljen (a https-re ügyeljünk!), a pénznemet állítsuk be (HUF), adjunk meg az admin vTiger felhasználónak egy erős, lehetőleg véletlen generált jelszót (az alapértelmezés admin - ne hagyjuk így!) és egy (lehetőleg nem személyes!) email címet;
  • az összefoglaló lapon ellenőrizzük az előzőeket;
  • ne kérjük a számunkra nem szükséges, opcionális modulokat - az alábbiak nem látszanak szükségesnek: SMSNotifier, CustomerPortal(?), ModComments és a nem releváns nyelvi csomagok;
  • hosszas (akár negyed órás!) molyolás után a telepítőprogram véget ér - a Finish nyomógomb a belépő oldalra visz, de még ne lépjünk be - az első belépés előtt végezzük el az utómunkálatokat.

Utómunkálatok

A telepítőprogram kikapcsolása

A virtualhost Apache konfigurációjában a komment eltávolításával tegyük elérhetetlenné a telepítőprogramot:

-rw-r--r-- root root /etc/apache2/sites-enabled/[FQHN]

[...]
    # Disable installer
    <LocationMatch "^/(install)|(install.php)">
        Order deny,allow
        Deny from all
    </LocationMatch>
[...]

A változtatást a webszerver konfiguráció újraolvastatásával érvényesítsük:

/etc/init.d/apache2 reload

A config.inc.php módosítása

Ez az állomány az adott vTiger példány általános beállításait tartalmazza. Célszerű az alábbi (webfelületről nem módosítható) beállításokat itt megtenni:

  • az ini_set hívás kommentezése - a memórialimitet az Apache konfigurációban szabályozzuk, a házirendben tiltott ini_set hívás csak a PHP hibanaplót tölti;
  • alapértelmezett a magyar nyelv;
  • TODO!
-rw-rw---- www-data www-data /var/www/[FQHN]config.inc.php

[...]
// memory limit default value = 64M
//ini_set('memory_limit','64M');

[...]
// default_language default value = en_us
$default_language = 'hu_hu';

[...]

Modulok hibajavítása

Csak v5.4.0 esetén kell elvégezni!

A kódkészlet patchelésekor a telepítő által bemásolt modulok még nem léteztek, így kimaradtak (viszont patchelni muszáj volt, enélkül nélkül a telepítő sem fut), így a patchet újra alkalmaznunk kell ezekre a modulokra. Ennek során a már patchelt fájlokat hagyjuk ki (Reversed (or previously applied) patch detected! Assume -R? [n] - enter, és Apply anyway? [n] - enter); a művelet végén takarítsuk el az emiatt keletkezett .rej állományokat és állítsuk helyre a patchelt állományok tulajdonosát (TODO: elegánsabb megoldást találni):

pwd                                                   # /var/www/[FQHN] legyen!
patch -p1 </root/tmp/vtigercrm-5.4.0-PHPv54-v2.patch  # Ellenőrizzük a nevét!

# Ami már patchelt (többség), azt NE fordítsuk vissza (ne legyen -R) és ne patcheljük újra,
# válaszoljuk az alapértelmezett nem, nem-et (enter, enter)

find . -name "*.rej" -exec rm {} \;                   # Reject fájlok törlése
find . -uid 0 -exec chown www-data:www-data {} \;     # Tulajdonos megjavítása

HTTPs forgalom kényszerítése

A virtualhost Apache konfigurációjában kényszerítsük HTTPs-re a forgalmat:

-rw-r--r-- root root /etc/apache2/sites-enabled/[FQHN]

[...]
   <IfModule mod_rewrite.c>
   [...]
        # Use to disable public http service (providing content only via https proxy).
        RewriteCond %{REMOTE_ADDR} !^(IP\.USED\.BY\.HTTPS-PROXY)$
        RewriteCond %{REMOTE_ADDR} !^(127\.0\.0\.1)$
        RewriteCond %{REMOTE_ADDR} !^(127\.0\.1\.1)$
        RewriteRule ^/(.*)         https://%{HTTP_HOST}/$1 [L,R,QSA]
   [...]
    </IfModule>
[...]

Ne feledjük a HTTPs-re kényszerítésnél a szervergép saját IP címét kitölteni! A változtatást a webszerver konfiguráció újraolvastatásával érvényesítsük:

/etc/init.d/apache2 reload

Ezek után a vTiger példány használatba vehető.

Használatba vétel

A kódkészlet frissítése

TODO!

Irodalom