Webszerver telepítése - Debian Jessie alapokon

Folytatva a Debian Jessie alapon történő építkezést, ebben a blogbejegyzés-sorozatban egy garantáltan működőképes webszervert fogunk felépíteni. A webszervert a már jól ismert alkatrészekből fogjuk összeállítani, úgymint Apache, PHP, MySQL, Postfix, Pure-FTPd, Clamav; valamint az egyes weboldalak tárhelyéhez kvótát is beállítunk annak érdekében, hogy kordában tartsuk a felhasználóink igényeit. A webszerverre több, egymástól különálló weboldalt is feltelepítünk az Apache VirtualHost képességének felhasználásával, hogy kipróbáljuk, ténylegesen működik éles helyzetben is mindaz, amit felépítettünk: ehhez pedig egy WordPress, egy Joomla! és egy Drupal alapú weboldalt is hadrendbe állítunk. Látni fogod, hogy egy új weboldal beindításához nem kevés konfigurációs fájlt kell hozzáadnunk a rendszerhez, éppen ezért ezt a folyamatot egy testreszabott bash szkripttel fogjuk megtámogatni. Innentől fogva viszont az új weboldalak hozzáadása gyerekjáték lesz.

A sorozat további részeiben szeretnék ennek a webszervernek a felhasználásával egy ILIAS és egy Moodle rendszert is felépíteni, a MySQL adatbázis-kezelőt MariaDB-re cserélni, valamint egy ügyes szkripttel az adatbázisok rendszeres (napi, heti és havi) mentését is megoldani. Szóval, ha időnként visszanézel hozzánk, biztosan fogsz találni érdekes kiegészítéseket mindahhoz, amit most felépítünk.

A rendszer felépítése

A webszervert virtuális környezetben, a hálózati telepítő segítségével, Oracle Virtualbox használatával készítettem el. A Debian alaprendszer telepítését Expert módban végeztem, az alábbi paraméterek felhasználásával:

  • Language – English
  • Location – Hungary
  • Locales – en_US.UTF-8, hu_HU.UTF-8
  • Keymap to use – Hungarian
  • IP címek: 192.168.1.200, 192.168.1.1, 8.8.8.8, 8.8.4.4
  • Hostname – webserver
  • Domain name – comega7.local
  • Time - NTP - Europe/Budapest
  • Lemez felhasználás - LVM (www): root (/,10GB), web (/srv/web,10GB), db (/srv/db,10GB), swap (2GB)
  • Debian archive mirror country - Hungary (ftp.hu.debian.org)
  • Non-free software - Yes
  • Services to use - security upates, release updates, backported software
  • Tasksel - SSH server
  • Grub - MBR (dev/sda)
  • UTC - Yes

A könnyebb használhatóság kedvéért:

apt-get install aptitude mc

Az alapértelmezett naplózó szolgáltatást cseréljük le:

aptitude install syslog-ng

Ha külön nem jelzem, a telepítések során mindenhol a Pa$$w0rd karaktersorozatot használom jelszóként.

Kvótarendszer beállítása

aptitude install quota quotatool

A /etc/fstab fájlt szerkesszük meg így:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system>        <mount point>    <type>        <options>        <dump>    <pass>
/dev/mapper/www-root     /               ext4          errors=remount-ro  0        1
/dev/mapper/www-db       /srv/db         ext4          defaults           0        2
/dev/mapper/www-web      /srv/web        ext4          defaults,usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0    0    2
/dev/mapper/www-swap     none            swap          sw                 0        0
/dev/sr0                 /media/cdrom0   udf,iso9660   user,noauto        0        0

Látható, hogy a weboldalak tárolására kialakított, a /srv/web mappába felcsatolt lemezköteten alakítjuk ki a kérdéses kvótarendszert. Az alábbi parancsokkal élesítsük be a kvótakezelést:

mount -o remount /srv/web
echo 'quota_v2' >> /etc/modules
rm /srv/web/aquota.user
rm /srv/web/aquota.group
quotacheck -avugm
quotaon -avug

És végül hozzuk létre a felcsatolt lemezköteten a www nevű mappát, amely a konkrét weboldalakat fogja tartalmazni:

mkdir /srv/web/www

MySQL telepítése

aptitude install mysql-server
mysql_secure_installation

Change root password: n
Remove anonymous users: Y
Disallow root login remotely? Y
Remove test database and access to it? Y
Reload privilege tables now? Y

Áthelyezzük az adatbázisokat a /srv/db/mysql mappába:

systemctl stop mysql
mkdir /srv/db/mysql
chown mysql:mysql /srv/db/mysql
mv /var/lib/mysql/* /srv/db/mysql

/etc/mysql/my.cnf fájlban egy sort módosítani kell:

...
datadir     = /var/lib/mysql
...

A fenti sort cseréljük le erre:

...
datadir     =/srv/db/mysql
...

Indítsuk újra a MySQL szervert:

systemctl start mysql

Apache és PHP-FPM telepítése

aptitude install apache2-mpm-worker php5-fpm
a2enmod proxy
a2enmod proxy_fcgi
systemctl restart apache2

/etc/php5/fpm/php.ini fájlban módosítsuk az alábbi paramétereket:

short_open_tag = On
max_execution_time = 300
sendmail_path = /usr/sbin/sendmail -t -i

Ahhoz, hogy működjön a névfeloldás, Linux alatt a /etc/hosts, Windows alatt pedig a C:\Windows\System32\drivers\etc\hosts fájlba kell egy sor:

192.168.1.200 webserver.comega7.local

A böngésződben látogasd meg a http://webserver.comega7.local oldalt. Ha eddig minden jól ment, akkor megjelenik az Apache2 Debian Default Page című oldal. Most pedig fogjuk munkára a PHP-t is:

cd /var/www/html
touch phpinfo.php

A fájl tartalma legyen ez:

<?php phpinfo(); ?>

A böngésződben most látogasd meg a http://webserver.comega7.local/phpinfo.php oldalt. A PHP egyelőre nem működik, a fájl tartalma fog megjelenni, nem pedig a phpinfo() függvény kimenete.

/etc/php5/fpm/pool.d/www.conf fájlban fogsz találni egy ilyen sort:

...
listen = /var/run/php5-fpm.sock
...

Vagyis a PHP értelmező a fenti unix socket fájlon keresztül várja a feldolgozási kérelmet, de ezt tudatnunk kell az Apache webszerverrel is. A /etc/apache2/sites-enabled/000-default.conf fájl tartalma legyen az alábbi:

<VirtualHost *:80>
    ServerName webserver.comega7.local
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    <Directory "/var/www/html">
        Options +SymLinksIfOwnerMatch
        AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,MultiViews
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/php5-fpm.sock|fcgi://localhost"
    </FilesMatch>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Látható, hogy a <FilesMatch> direktíván belül mondjuk meg az Apache számára azt, hogy ha PHP fájlokkal találkozik, hová kell azokat elküldenie feldolgozásra.

systemctl restart apache2

A böngésződben látogasd meg ismét a http://webserver.comega7.local/phpinfo.php oldalt. A phpinfo() függvény teszi a dolgát, Neked pedig van egy működő Apache-PHP duód.

A weboldalak tárolásához alakítsuk ki az alábbi sablont:

mkdir /etc/skel/www-site
mkdir /etc/skel/www-data
mkdir /etc/skel/log-files

A www-site mappa fogja tárolni a weboldalakat, a www-data mappa a weboldalak azon adatait, amelyeket nem szabad közvetlenül elérni az Internet felől, a log-files mappa pedig az oldalhoz tartozó Apache és PHP logokat.

Postfix telepítése

aptitude install postfix

A levelezőszerver beállításai: típusa = internet site, név = webserver.comega7.local

Szükségünk lesz a kimenő levelek feladó címének átírására (a tesztrendszerem domain neve ugyanis comega7.local). Erre a beállításra tisztességes nevű éles szerver esetén persze nem lesz szükséged.

touch /etc/postfix/generic
postmap /etc/postfix/generic

A fenti fájlt - legalábbis egyelőre - üresen hagyjuk. A /etc/postfix/main.cf fájlba vegyük fel az alábbi sort:

...
smtp_generic_maps = hash:/etc/postfix/generic
...

Indítsuk újra a Postfix levelezőt:

systemclt restart postfix

Weboldalak telepítése - áttekintés

Miután a rendszer alapjait lefektettük, jöhet az első weboldal beüzemelése is. Mindegyik weboldal beállításához az alábbi műveleteket fogjuk végrehajtani:

  • létrehozunk egy linux felhasználót, akinek a nevében a PHP kódok futnak,
  • elkészítjük és beállítjuk a weboldalak tárolására a megfelelő mappastruktúrát,
  • beállítjuk a kvóta adatokat,
  • elkészítjük az Apache konfigurációs fájlt,
  • elkészítjük a PHP konfigurációs fájlt,
  • elkészítjük a log fájlok forgatásához szükséges konfigurációs fájlt,
  • elkészítjük a weboldalhoz szükséges adatbázist,
  • és végül feltelepítjük magát a weboldalt is.

A fenti lépéseket minden weboldal esetén el kell végeznünk. Ezt először kézzel fogjuk csinálni, de azután a fenti lépések legtöbbjét egy takaros kis szkriptre fogjuk bízni, amely leveszi a munka unalmas részét a vállunkról.

WordPress telepítése

WordPress felhasználó hozzáadása:

useradd -b /srv/web/www -g www-data -k /etc/skel -m -N -s /bin/false -p Pa$$w0rd wordpress.comega7.local

Webkönyvtár kialakítása:

chown -R wordpress.comega7.local:www-data /srv/web/www/wordpress.comega7.local
find /srv/web/www/wordpress.comega7.local -type f -exec rm -f {} \;
find /srv/web/www/wordpress.comega7.local -type d -exec chmod 0550 {} \;
chmod 750 /srv/web/www/wordpress.comega7.local/www-data
chmod 750 /srv/web/www/wordpress.comega7.local/www-site
chmod 750 /srv/web/www/wordpress.comega7.local/log-files
chattr +i /srv/web/www/wordpress.comega7.local

Kvóta beállítása (hard quota: 1GB, soft quota: 80%, a fájlok darabszámára nézve pedig nincs korlátozás):

setquota -u wordpress.comega7.local 1048576 838861 0 0 -a /dev/mapper/www-web

PHP beállítása:

touch /etc/php5/fpm/pool.d/wordpress.comega7.local.conf

A /etc/php5/fpm/pool.d/wordpress.comega7.local.conf fájl tartalma:

[wordpress.comega7.local]
user = wordpress.comega7.local
group = www-data
listen = /var/run/wordpress.comega7.local.php5-fpm.sock
listen.owner = wordpress.comega7.local
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/wordpress.comega7.local.fpm-php.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 128M

A PHP-FPM újraindítása:

systemctl restart php5-fpm

Apache beállítása:

touch /etc/apache2/sites-available/wordpress.comega7.local.conf

/etc/apache2/sites-available/wordpress.comega7.local.conf fájl tartalma:

<VirtualHost *:80>
    ServerName          wordpress.comega7.local
    ServerAdmin         webmaster@comega7.local
    DocumentRoot        /srv/web/www/wordpress.comega7.local/www-site/

    <Directory "/srv/web/www/wordpress.comega7.local/www-site">
        Options +SymLinksIfOwnerMatch
        AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,MultiViews
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/wordpress.comega7.local.php5-fpm.sock|fcgi://localhost"
    </FilesMatch>

    ErrorLog      /srv/web/www/wordpress.comega7.local/log-files/wordpress.comega7.local.error.log
    CustomLog     /srv/web/www/wordpress.comega7.local/log-files/wordpress.comega7.local.access.log combined
</VirtualHost>

Az oldal engedélyezése és az Apache újraindítása:

a2ensite wordpress.comega7.local
systemctl restart apache2

Logfájlok forgatása:

mkdir /etc/logrotate.d/www
touch /etc/logrotate.d/www/wordpress.comega7.local

/etc/logrotate.d/www/wordpress.comega7.local fájl tartalma:

/srv/web/www/wordpress.comega7.local/log-files/*.log {
    weekly
    missingok
    rotate 12
    compress
    delaycompress
    notifempty
    create 640 wordpress.comega7.local www-data
    sharedscripts
    postrotate
                if /etc/init.d/apache2 status > /dev/null ; then \
                    /etc/init.d/apache2 reload > /dev/null; \
                fi;
    endscript
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi;\
    endscript
}

A /etc/logrotate.conf fájlba szúrjunk be egy sort (/www):

...
# packages drop log rotation information into this directory
include /etc/logrotate.d
include /etc/logrotate.d/www
...

A kliens gépünk hosts fájlját egészítsük ki:

192.168.1.200   webserver.comega7.local wordpress.comega7.local

Wordpress telepítő letöltése és bemásolása (a cikk írásakor elérhető legfrissebb változattal):

cd /tmp
wget --no-check-certificate https://hu.wordpress.org/wordpress-4.3.1-hu_HU.zip
unzip wordpress-4.3.1-hu_HU.zip
cp -a /tmp/wordpress/. /srv/web/www/wordpress.comega7.local/www-site
chown -R wordpress.comega7.local:www-data /srv/web/www/wordpress.comega7.local/www-site
find /srv/web/www/wordpress.comega7.local/www-site -type f -exec chmod 0640 {} \;
find /srv/web/www/wordpress.comega7.local/www-site -type d -exec chmod 0750 {} \;

Wordpress adatbázis elkészítése:

mysql -u root -p
CREATE DATABASE wordpress CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON wordpress.* TO wordpress@localhost IDENTIFIED BY 'Pa$$w0rd';
FLUSH PRIVILEGES;
exit

Kell egy új csomagot adnunk a rendszerhez:

aptitude install php5-mysqlnd

A levelezőszerver beállításait is módosítanunk kell (de csak tesztrendszer esetén):

A /etc/postfix/generic fájl tartama legyen:

wordpress.comega7.local@webserver.comega7.local        wordpress.comega7.local@comega7.hu

A beállítás szerint a WordPress által küldött levelek a comega7.hu tartományból érkeznek (nem pedig a comega7.local-ból). Ezeket a levelezőszerverem csak a telepítés idejére fogadta el, néhány biztonsági ellenőrzés kikapcsolása mellett (amelyeket már - nem mellesleg - mind visszakapcsoltam). Neked a második e-mail cím helyére egy saját és működő címet kell írnod, hogy Te is megkapd a WordPress leveleit. Juttassuk érvényre a fenti beállításokat:

postmap /etc/postfix/generic
systemctl restart postfix

A böngészőben nyissuk meg a http://wordpress.comega7.local oldalt. Elindul a telepítő:

WordPress - 1

Meg kell adnunk az adatbázishoz való kapcsolódás adatait:

WordPress - 2

Az adatbázis kapcsolat megvan, mehetünk tovább:

WordPress - 3

A weboldal használatához szükséges alapvető adatok megadása következik:

WordPress - 4

Vicces fiúk ezek a WordPress fejlesztők:

WordPress - 5

Beléphetünk az adminisztrációs felületre:

WordPress - 6

Neki is állhatunk felépíteni az oldalt (struktúra, sminkek, stb):

WordPress - 7

És maga az oldal a látogatók szemével, még mindenféle értékelhető tartalom nélkül:

WordPress - 8

Magával a WordPress oldal felépítésével nem foglalkozom tovább, a cél "csak" annyi volt, hogy működésre bírjuk. És ez láthatólag sikerült is. :-) A telepítőtől pedig az alábbi levelet kaptam:

Az új WordPress-alapú honlap sikeresen beállítvat:

http://wordpress.comega7.local

A következő információk birtokában léphetünk be az adminisztrációs felületre:

Felhasználónév: b_attila
Jelszó: A jelszó a telepítés során került meghatározásra.
Bejelentkezés címe: http://wordpress.comega7.local/wp-login.php

Reméljük, hogy az új honlap sok örömet fog nyújtani - köszönjük szépen!

-WordPress Magyarország Közösség
https://wphu.org/

Joomla! telepítése

Felhasználó hozzáadása:

useradd -b /srv/web/www -g www-data -k /etc/skel -m -N -s /bin/false -p Pa$$w0rd joomla.comega7.local

Webkönyvtár kialakítása:

chown -R joomla.comega7.local:www-data /srv/web/www/joomla.comega7.local
find /srv/web/www/joomla.comega7.local -type f -exec rm -f {} \;
find /srv/web/www/joomla.comega7.local -type d -exec chmod 0550 {} \;
chmod 750 /srv/web/www/joomla.comega7.local/www-data
chmod 750 /srv/web/www/joomla.comega7.local/www-site
chmod 750 /srv/web/www/joomla.comega7.local/log-files
chattr +i /srv/web/www/joomla.comega7.local

Kvóta beállítása:

setquota -u joomla.comega7.local 1048576 838861 0 0 -a /dev/mapper/www-web

PHP beállítása:

touch /etc/php5/fpm/pool.d/joomla.comega7.local.conf

A /etc/php5/fpm/pool.d/joomla.comega7.local.conf fájl tartalma:

[joomla.comega7.local]
user = joomla.comega7.local
group = www-data
listen = /var/run/joomla.comega7.local.php5-fpm.sock
listen.owner = joomla.comega7.local
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
php_flag[display_errors] = off
php_admin_value[error_log] = /var/log/joomla.comega7.local.fpm-php.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 128M

A PHP-FPM újraindítása:

systemctl restart php5-fpm

Apache virtualhost beállítása:

touch /etc/apache2/sites-available/joomla.comega7.local.conf

A /etc/apache2/sites-available/joomla.comega7.local.conf fájl tartalma:

<VirtualHost *:80>
    ServerName          joomla.comega7.local
    ServerAdmin         webmaster@comega7.local
    DocumentRoot        /srv/web/www/joomla.comega7.local/www-site/

    <Directory "/srv/web/www/joomla.comega7.local/www-site">
        Options +SymLinksIfOwnerMatch
        AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,MultiViews
        Require all granted
    </Directory>

    <FilesMatch \.php$>
        SetHandler "proxy:unix:/var/run/joomla.comega7.local.php5-fpm.sock|fcgi://localhost"
    </FilesMatch>

    ErrorLog      /srv/web/www/joomla.comega7.local/log-files/joomla.comega7.local.error.log
    CustomLog     /srv/web/www/joomla.comega7.local/log-files/joomla.comega7.local.access.log combined
</VirtualHost>

Az oldal engedélyezése és az Apache újraindítása:

a2ensite joomla.comega7.local
systemctl restart apache2

Logfájlok forgatásának beállítása:

touch /etc/logrotate.d/www/joomla.comega7.local

/etc/logrotate.d/www/joomla.comega7.local fájl tartalma:

/srv/web/www/joomla.comega7.local/log-files/*.log {
    weekly
    missingok
    rotate 12
    compress
    delaycompress
    notifempty
    create 640 joomla.comega7.local www-data
    sharedscripts
    postrotate
                if /etc/init.d/apache2 status > /dev/null ; then \
                    /etc/init.d/apache2 reload > /dev/null; \
                fi;
    endscript
    prerotate
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi;\
    endscript
}

A kliens gép hosts fájlja legyen:

192.168.1.200   webserver.comega7.local wordpress.comega7.local joomla.comega7.local

Joomla telepítő letöltése és bemásolása:

cd /tmp
wget --no-check-certificate http://joomlacms.hu/let%C3%B6lt%C3%A9sek/joomla/telep%C3%ADt%C5%91-csomag?download=135:joomla-3-4-5 -O Joomla_3.4.5-Stable-Full_Package.zip
unzip Joomla_3.4.5-Stable-Full_Package.zip -d /srv/web/www/joomla.comega7.local/www-site
chown -R joomla.comega7.local:www-data /srv/web/www/joomla.comega7.local/www-site
find /srv/web/www/joomla.comega7.local/www-site -type f -exec chmod 0640 {} \;
find /srv/web/www/joomla.comega7.local/www-site -type d -exec chmod 0750 {} \;

Joomla adatbázis elkészítése:

mysql -u root -p
CREATE DATABASE joomla CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON joomla.* TO joomla@localhost IDENTIFIED BY 'Pa$$w0rd';
FLUSH PRIVILEGES;
exit

Levelezőszerver beállítása:

A /etc/postfix/generic fájl tartalma:

wordpress.comega7.local@webserver.comega7.local  wordpress.comega7.local@comega7.hu
joomla.comega7.local@webserver.comega7.local     joomla.comega7.local@comega7.hu

Juttassuk érvényre a beállításokat:

postmap /etc/postfix/generic
service postfix restart

A böngészőben nyissuk meg a http://joomla.comega7.local oldalt. Elindul a telepítő, ahol ismét az alapvető információk megadása következik:

Joomla - 1

Az adatbázishoz való kapcsolódás adatai:

Joomla - 2

Jöhet a nyelvek telepítése:

Joomla - 3

Keressük ki a magyart és jelöljük be:

Joomla - 4

Az alapértelmezett mindkét esetben legyen a magyar nyelv:

Joomla - 5

Jöhet az installation mappa eltávolítása:

Joomla - 6

Ezzel is megvagyunk:

Joomla - 7

Az alábbi levelet kaptam a telepítőtől:

Az alábbiakban megtaláható az újonnan telepített Joomla! oldal konfigurációja:

Webhely neve:       Joomla! - példa

Adminisztráció bejelentkezési adatai
=======================================
E-mail cím:        bolemanyi.attila@comega7.hu
Felhasználónév:  b_attila

Adatbázis konfigurálása
==========================
Adatbázis típusa: mysqli
Állomás neve:     localhost
Felhasználónév:  joomla
Adatbázisnév:     joomla
Táblanév előtag: bjag0_

Automatizáljuk a dolgokat!

Amint azt a bevezetőben is említettem, célszerű a leggyakrabban elvégzett konfigurációs műveleteket egy szript segítségével elvégeztetni. Nekünk csak annyi lesz a dolgunk, hogy megadunk néhány kiinduló adatot, a rabszolgamunkát pedig rábízzuk a szriptre. Az alábbiakban közreadott bash szkript sem nem szép, sem nem elegáns, vagyis pont olyan, mint egy barkácsolt hátvakaró, amely éppen ott segít, ahol a legjobban viszket. De a dolgát elvégzi, ahogyan kell. Használd fel nyugodtan, módosítsd, ahogyan azt a szükségeid kívánják, vagy csak egyszerűen tanulj belőle.

#!/bin/bash

##########################################################################
# Creating the website user and its configuration files.                 #
##########################################################################

WEBDIR="/srv/web/www"
WEBGROUP="www-data"
SKEL="/etc/skel"
SHELL="/bin/false"
APACHE_CONFIG_DIR="/etc/apache2/sites-available/"
FPM_POOL_DIR="/etc/php5/fpm/pool.d/"
LOGROTATE_CONFIG_DIR="/etc/logrotate.d/www/"

# Default hard quota in GB
HARDQUOTA="1"

# Default soft quota in %
SOFTQUOTA="80"

# Mount point (filesystem with quota)
MPOINT="/dev/www/web"

EMAIL="bolemanyi.attila@comega7.hu"
MESSAGE="/tmp/message.txt"

# Function to generate a random password
#  $1 = number of characters; defaults to 32
#  $2 = include special characters; 1 = yes, 0 = no; defaults to 1
function randpass() {
  [ "$2" == "0" ] && CHAR="[:alnum:]" || CHAR="[:graph:]"
  cat /dev/urandom | tr -cd "$CHAR" | head -c ${1:-32}
  echo
}

#########################
# Creating website user #
#########################

if [ $(id -u) -eq 0 ]; then
    read -p "Enter full website name (test.example.com): " USERNAME
    read -s -p "Enter password (or press ENTER to generate a random one): " PASSWORD
    if [ -z "$PASSWORD" ]
    then
    PASSWORD=$(randpass "16" "0")
    echo ""
    fi
    read -p "Enter quota size in GB (default=1): " QUOTA
    if [ -z "$QUOTA" ];then
    QUOTA=$HARDQUOTA
    fi
    echo ""
    egrep "^$USERNAME" /etc/passwd >/dev/null
    if [ $? -eq 0 ]; then
    echo "The website: $USERNAME has been already created!"
    exit 1
    else
    pass=$(perl -e 'print crypt($ARGV[0], "password")' $PASSWORD)
    useradd -b $WEBDIR -G $WEBGROUP -k $SKEL -m -N -s $SHELL -p $pass $USERNAME
    [ $? -eq 0 ] && echo "The website user has been added to the system!" || echo "Failed to add a user!"
    fi
else
    echo "Only root may add a website to the system"
    exit 2
fi

####################################################################
# Cleaning up website directory and setting up filesystem security #
####################################################################

HOME=$WEBDIR/$USERNAME

chown -R $USERNAME:$WEBGROUP $HOME
find $HOME -type f -exec rm -f {} \;
find $HOME -type d -exec chmod 0550 {} \;
chmod 750 $HOME"/www-data"
chmod 750 $HOME"/www-site"
chmod 750 $HOME"/log-files"
chattr +i $HOME
echo "Website home directory has been created and set up."

################################
# Setting up quota (in kBytes) #
################################

HARD_SIZE=$(echo "$QUOTA*1024*1024" | bc)
SOFT_SIZE=$(echo "$QUOTA*1024*1024/100*$SOFTQUOTA" | bc)
setquota -u $USERNAME $SOFT_SIZE $HARD_SIZE 0 0 -a $MPOINT
echo "Quota has been set up."

#####################################
# Creating FPM pool definition file #
#####################################

FCGI_SOCKET_FILE="/var/run/"$USERNAME".php5-fpm.sock"
FPM_POOL_FILE=$FPM_POOL_DIR$USERNAME".conf"

if [ ! -f $FPM_POOL_FILE ]; then
    echo "Creating FPM/PHP pool definition file..."
    
    touch $FPM_POOL_FILE
    echo "["$USERNAME"]" >> $FPM_POOL_FILE
    echo "" >> $FPM_POOL_FILE
    echo "user = "$USERNAME >> $FPM_POOL_FILE
    echo "group = "$WEBGROUP >> $FPM_POOL_FILE
    echo "" >> $FPM_POOL_FILE
    echo "listen = "$FCGI_SOCKET_FILE >> $FPM_POOL_FILE
    echo "listen.backlog = 128" >> $FPM_POOL_FILE
    echo "listen.owner = "$USERNAME >> $FPM_POOL_FILE
    echo "listen.group = "$WEBGROUP >> $FPM_POOL_FILE
    echo "listen.mode = 0660" >> $FPM_POOL_FILE
    echo "" >> $FPM_POOL_FILE
    echo "pm = dynamic" >> $FPM_POOL_FILE
    echo "pm.max_children = 5" >> $FPM_POOL_FILE
    echo "pm.start_servers = 2" >> $FPM_POOL_FILE
    echo "pm.min_spare_servers = 1" >> $FPM_POOL_FILE
    echo "pm.max_spare_servers = 3" >> $FPM_POOL_FILE
    echo "" >> $FPM_POOL_FILE
    echo "php_admin_flag[display_errors] = off" >> $FPM_POOL_FILE
    echo "php_admin_value[error_log] = "$HOME"/log-files/fpm-php.error.log" >> $FPM_POOL_FILE
    echo "php_admin_flag[log_errors] = on" >> $FPM_POOL_FILE
    echo "php_admin_value[memory_limit] = 128M" >> $FPM_POOL_FILE

    echo "Restarting FPM/PHP service..."
    systemctl restart php5-fpm
else
    echo "The file: "$FPM_POOL_FILE" already exists!"
fi

##################################################
# Creating Apache virtualhost configuration file #
##################################################

APACHE_CONFIG_FILE=$APACHE_CONFIG_DIR$USERNAME".conf"

if [ ! -f $APACHE_CONFIG_FILE ]; then
    echo "Creating Apache configuration file..."

    touch $APACHE_CONFIG_FILE
    echo "<VirtualHost *:80>" >> $APACHE_CONFIG_FILE
    echo " ServerName "$USERNAME >> $APACHE_CONFIG_FILE
    echo " ServerAdmin webmaster@comega7.local" >> $APACHE_CONFIG_FILE
    echo " DocumentRoot "$HOME"/www-site/" >> $APACHE_CONFIG_FILE
    echo "" >> $APACHE_CONFIG_FILE
    echo " <Directory \""$HOME"/www-site\">" >> $APACHE_CONFIG_FILE
    echo " Options +SymLinksIfOwnerMatch" >> $APACHE_CONFIG_FILE
    echo " AllowOverride Authconfig FileInfo Indexes Limit Options=Indexes,MultiViews" >> $APACHE_CONFIG_FILE
    echo " Require all granted" >> $APACHE_CONFIG_FILE
    echo " </Directory>" >> $APACHE_CONFIG_FILE
    echo "" >> $APACHE_CONFIG_FILE
    echo " <FilesMatch \\.php$>" >> $APACHE_CONFIG_FILE
    echo " SetHandler \"proxy:unix:"$FCGI_SOCKET_FILE"|fcgi://localhost\"" >> $APACHE_CONFIG_FILE
    echo " </FilesMatch>" >> $APACHE_CONFIG_FILE
    echo "" >> $APACHE_CONFIG_FILE
    echo " ErrorLog "$HOME"/log-files/error.log" >> $APACHE_CONFIG_FILE
    echo " CustomLog "$HOME"/log-files/access.log combined" >> $APACHE_CONFIG_FILE
    echo "</VirtualHost>" >> $APACHE_CONFIG_FILE

    echo "Enabling website config..."
    a2ensite $USERNAME
    echo "Restarting Apache webserver..."
    systemctl restart apache2
else
    echo "The file: "$APACHE_CONFIG_FILE" already exists!"
fi

########################################
# Setting up Apache log files rotation #
########################################

LOGROTATE_CONFIG_FILE=$LOGROTATE_CONFIG_DIR$USERNAME

if [ ! -f $LOGROTATE_CONFIG_FILE ]; then
    echo "Creating Apache log files rotation configuration file..."

    touch $LOGROTATE_CONFIG_FILE
    echo $HOME"/log-files/*.log {" >> $LOGROTATE_CONFIG_FILE
    echo " weekly" >> $LOGROTATE_CONFIG_FILE
    echo " missingok" >> $LOGROTATE_CONFIG_FILE
    echo " rotate 12" >> $LOGROTATE_CONFIG_FILE
    echo " compress" >> $LOGROTATE_CONFIG_FILE
    echo " delaycompress" >> $LOGROTATE_CONFIG_FILE
    echo " notifempty" >> $LOGROTATE_CONFIG_FILE
    echo " create 440 "$USERNAME" "$WEBGROUP >> $LOGROTATE_CONFIG_FILE
    echo " sharedscripts" >> $LOGROTATE_CONFIG_FILE
    echo " postrotate" >> $LOGROTATE_CONFIG_FILE
    echo " if /etc/init.d/apache2 status > /dev/null ; then \\" >> $LOGROTATE_CONFIG_FILE
    echo " /etc/init.d/apache2 reload > /dev/null ; \\" >> $LOGROTATE_CONFIG_FILE
    echo " fi;\\" >> $LOGROTATE_CONFIG_FILE
    echo " endscript" >> $LOGROTATE_CONFIG_FILE
    echo " prerotate" >> $LOGROTATE_CONFIG_FILE
    echo " if [ -d /etc/logrotate.d/httpd-prerotate ]; then \\" >> $LOGROTATE_CONFIG_FILE
    echo " run-parts /etc/logrotate.d/httpd-prerotate; \\" >> $LOGROTATE_CONFIG_FILE
    echo " fi;\\" >> $LOGROTATE_CONFIG_FILE
    echo " endscript" >> $LOGROTATE_CONFIG_FILE
    echo "}" >> $LOGROTATE_CONFIG_FILE
else
    echo "The file: "$LOGROTATE_CONFIG_FILE" already exists!"
fi

#################################
# Sending e-mail about this job #
#################################

SUBJECT="Created website at webserver.comega7.local - "$USERNAME

echo "Hello, Admin!" > $MESSAGE
echo "" >> $MESSAGE
echo "I have just created a website with these parameters:" >> $MESSAGE
echo "" >> $MESSAGE
echo "Website URL (and FTP username): "$USERNAME >> $MESSAGE
echo "Password: "$PASSWORD >> $MESSAGE
R_HQUOTA=$(repquota $MPOINT | grep $USERNAME | awk '{print $5}')
R_SQUOTA=$(repquota $MPOINT | grep $USERNAME | awk '{print $4}')
REAL_HQUOTA=$(echo "scale=2; $R_HQUOTA/1024/1024" | bc )
REAL_SQUOTA=$(echo "scale=2; $R_SQUOTA/1024/1024" | bc )
echo "Hard quota size: "$REAL_HQUOTA" GB" >> $MESSAGE
echo "Soft quota size: "$REAL_SQUOTA" GB" >> $MESSAGE
echo "Web folder (for public web pages): www-site" >> $MESSAGE
echo "Data folder (unseen from the Internet): www-data" >> $MESSAGE
echo "Webserver log folder: log-files" >> $MESSAGE
echo "" >> $MESSAGE
echo "Your fantastic bash script ;-)" >> $MESSAGE
/usr/bin/mail -s "$SUBJECT" "$EMAIL" < $MESSAGE
echo "" > $MESSAGE

A fenti szkriptet mentsük el create-website-folder.sh néven és adjunk a számára futási jogot is, majd helyezzük el a /usr/bin mappában. A szkript működéséhez szükség lesz a mail és a bc parancsra is:

aptitude install mailutils bc

A tesztrendszeremen ez újabb módosítást igényel a Postfixen belül is. A /etc/postfix/generic fájl tartalma (a leveleket a root felhasználó küldi):

wordpress.comega7.local@webserver.comega7.local     wordpress.comega7.local@comega7.hu
joomla.comega7.local@webserver.comega7.local        joomla.comega7.local@comega7.hu
root@webserver.comega7.local                        root@comega7.hu

Juttassuk érvényre a fenti beállításokat:

postmap /etc/postfix/generic
systemctl restart postfix

A szkript mostantól működőképes és e-mailt is küld mindarról, amit elvégzett értünk.

Drupal telepítése

Ha már van egy segítő társunk, fogjuk is munkára:

root@webserver:~# create-website-folder.sh
Enter full website name (test.example.com): drupal.comega7.local
Enter password (or press ENTER to generate a random one):
Enter quota size in GB (default=1):

The website user has been added to the system!
Website home directory has been created and set up.
Quota has been set up.
Creating FPM/PHP pool definition file...
Restarting FPM/PHP service...
Creating Apache configuration file...
Enabling website config...
Enabling site drupal.comega7.local.
To activate the new configuration, you need to run:
  service apache2 reload
Restarting Apache webserver...
Creating Apache log files rotation configuration file...
root@webserver:~#

A levél tartalma pedig, amit a szkript küldött:

Hello, Admin!

I have just created a website with these parameters:

Website URL (and FTP username): drupal.comega7.local
Password: gdFVL0cvL1nqhn13
Hard quota size: 1.00 GB
Soft quota size: .79 GB
Web folder (for public web pages): www-site
Data folder (unseen from the Internet): www-data
Webserver log folder: log-files

Your fantastic bash script

Ismét szükség van egy kis módosításra a tesztrendszer levelezőszerverében:

/etc/postfix/generic fájl tartalma:

wordpress.comega7.local@webserver.comega7.local     wordpress.comega7.local@comega7.hu
joomla.comega7.local@webserver.comega7.local        joomla.comega7.local@comega7.hu
root@webserver.comega7.local                        root@comega7.hu
drupal.comega7.local@webserver.comega7.local        drupal.comega7.local@comega7.hu

Juttassuk érvényre a fenti beállításokat:

postmap /etc/postfix/generic
systemctl restart postfix

Drupal adatbázis készítése:

mysql -u root -p
CREATE DATABASE drupal CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON drupal.* TO drupal IDENTIFIED BY 'Pa$$w0rd';
FLUSH PRIVILEGES;
exit

Ezt a lépést nem tettem be a szkriptbe, mert nem minden weboldalnak van szüksége adatbázisra is. De ha gondolod, akkor van egy házi feladatod: módosítsd úgy a szkriptet, hogy az adatbázis és annak felhasználója nevét valamint jelszavát is kérje be (vagy generáljon egyet), és készítse el ezt is ;-)

A Drupal letöltése és elhelyezése:

cd /tmp
wget http://ftp.drupal.org/files/projects/drupal-7.41.tar.gz
tar -xzf drupal-7.41.tar.gz
wget http://ftp.drupal.org/files/translations/7.x/drupal/drupal-7.41.hu.po
cp ./drupal-7.41.hu.po /tmp/drupal-7.41/profiles/standard/translations
cp -a /tmp/drupal-7.41/. /srv/web/www/drupal.comega7.local/www-site
chown -R drupal.comega7.local:www-data /srv/web/www/drupal.comega7.local/www-site
find /srv/web/www/drupal.comega7.local/www-site -type f -exec chmod 0640 {} \;
find /srv/web/www/drupal.comega7.local/www-site -type d -exec chmod 0750 {} \;

A kliens gép hosts fájlja pedig:

192.168.1.200   webserver.comega7.local wordpress.comega7.local joomla.comega7.local drupal.comega7.local

A /srv/web/www/drupal.comega7.local/www-site/.htaccess fájl 14. sorát módosítsd az alábbiak szerint (ellenkező esetben a telepítő helyett egy barátságtalan Internal Server Error üzenetet fogsz találni):

# Options +FollowSymLinks

A Drupal igényel még egy PHP kiegészítő csomagot is:

aptitude install php5-gd

És akkor a böngészőben indulhat a telepítés (http://drupal.comega7.local). A Standard profilra lesz szükségünk:

Drupal - 1

Válasszuk a magyar nyelvet:

Drupal - 2

Adjuk meg a Drupalhoz tartozó adatbázis adatait:

Drupal - 3

Dolgozik a telepítő:

Drupal - 4

Adjuk meg a webhely alapvető adatait:

Drupal - 5

Elkészült a telepítés:

Drupal - 6

Kezdhetjük az építkezést:

Drupal - 7

Pure-FTPd és Clamav telepítése

Utolsó lépésként pedig telepítsük fel a Pure-FTPd szolgáltatást és a Clamav víruskeresőt úgy, hogy az FTP-n feltöltött fájlok menjenek keresztül a víruskeresőn is.

aptitude install pure-ftpd clamav clamav-daemon
touch /etc/pure-ftpd/upload.sh
chmod +x /etc/pure-ftpd/upload.sh

A /etc/pure-ftpd/upload.sh tartalma:

#!/bin/sh
/usr/bin/clamdscan --fdpass --remove --quiet --no-summary "$1"

/etc/clamav/clamd.conf fájlban cseréld ki az alapértelmezett FALSE értéket erre:

AllowSupplementaryGroups true

/etc/pure-ftpd/auth mappában található fájlok tartalma legyen ez:

65unix - "yes"
70pam  - "yes"

/etc/pure-ftpd/conf mappában pedig az alábbi fájlokat hozd létre a mellé írt tartalommal:

CallUploadScript - "yes"
ChrootEveryone   - "yes"
DisplayDotFiles  - "yes"
ForcePassiveIP   - "192.168.1.200"
PassivePortRange - "2000 2999"
TLS              - "2"
Umask            - "027 027"

Természetesen mindenhol idézőjelek nélkül...

/etc/default/pure-ftpd-common fájlban az alábbi paramétereknek add ezeket az értékeket:

VIRTUALCHROOT = true
UPLOADSCRIPT  = /etc/pure-ftpd/upload.sh

A /etc/shells fájlhoz adj egy új sort:

/bin/false

Mivel csak titkosított FTP kapcsolatot engedélyezünk, kell egy tanúsítvány is (amit most mi írunk alá):

openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem

A válaszok pedig:

Country Name (2 letter code) [AU]:HU
State or Province Name (full name) [Some-State]:Pest
Locality Name (eg, city) []:Budapest
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Comega7
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:webserver.comega7.local
Email Address []:bolemanyi.attila@comega7.hu

A Common Name értéke legyen a webszervered FQDN neve!

chmod 600 /etc/ssl/private/*.pem
systemctl restart pure-ftpd

Ha FTP-n szeretnél csatlakozni az egyik oldalhoz, használhatod többek között a FileZilla programot is. A beállítások így néznek ki:

FileZilla - 3

A tanúsítványra persze hogy panaszkodik, hiszen mi írtuk alá. Fogadjuk el:

FileZilla - 1

Íme a webkönyvtár:

FileZilla - 2

Ha megpróbálsz feltölteni egy vírusos fájlt - mondjuk a www-data mappába - akkor azt azonnal törli a Clamav, és nem engedi felmásolni a szerverre. Tesztelési célból innen tudsz letölteni ártalmatlan vírusmintát tartalmazó fájlt: http://www.eicar.org/85-0-Download.html

/var/log/clamav/clamav.log fájlban ezt fogod találni, ha megpróbálod feltölteni:

Wed Nov  3 17:54:33 2015 -> fd[10]: Eicar-Test-Signature(44d88612fea8a8f36de82e1278abb02f:68) FOUND

Azaz a Clamav teszi a dolgát és minden feltöltött fájlt át fog vizsgálni.