3.9. Hosting

Zarządzanie różnymi usługami na serwerze jest teraz możliwe. Funkcjonalność ta jest przeznaczona dla zaawansowanych użytkowników. Wymaga znajomości tych usług i ich konfiguracji w celu korzystania z bazy danych.

W LMSie można utworzyć pięć rodzajów kont: shell (1), poczta (2), www (4), ftp (8) i sql (16). W nawiasach podano numeryczne wewnętrzne oznaczenie typu konta w bazie. Konta mogą być wielotypowe. Przykładowo, jeśli zdefiniujesz konto shell+poczta+ftp w bazie zostanie zapisana cyfra 11. Oznacza to, że do rozpoznawania typu konta w warunkach WHERE zapytań SQL należy stosować sumowanie binarne (jak na przykładach w dalszej części rozdziału).

Masz także możliwość definiowania domen i aliasów.

3.9.1. Konta

Na liście przedstawione są podstawowe informacje o kontach. Możliwe jest dowolne sortowanie listy poprzez kliknięcie nazwy kolumny oraz filtrowanie wg zadanych kryteriów. Przejście do edycji danych konta następuje po wybraniu ikony [Edytuj]. Użytkownik ma także prawo do zmiany hasła.

3.9.2. Nowe konto

Definiując dane konto musisz podać login, hasło, wybrać domenę, wybrać typ konta oraz przypisać klienta (lub utworzyć tzw. konto systemowe). Data ważności konta jest opcjonalna. Pozostawienie pustego pola z datą oznacza, że konto nigdy nie wygasa.

Masz możliwość zdefiniować dowolny katalog domowy użytkownika (konta). Opcja konfiguracyjna homedir_prefix w sekcji [phpui] zawiera prefix katalogu domowego, domyślnie ustawiony na wartość "/home/".

3.9.3. Aliasy

Konta (głównie mailowe) mogą posiadać dowolną ilość aliasów. Administrator serwera pocztowego może przekierować (lokalnie) pocztę z wszystkich aliasów do jednego konta. Na liście aliasów przedstawione są podstawowe informacje o nich i o kontach na które aliasy te wskazują. Możliwe jest dowolne sortowanie listy poprzez kliknięcie nazwy kolumny oraz filtrowanie wg zadanych kryteriów.

3.9.4. Nowy alias

Tworząc alias definiujesz dla niego login i domenę oraz cel. Celem może być jedno lub więcej istniejących kont. Uwaga: aby utworzyć alias do konta, które znajduje się na obcym serwerze należy utworzyć konto i podać adres przekierowania.

3.9.5. Domeny

Obecnie LMS może bezpośrednio zarządzać serwerem PowerDNS z mysql/pqsl backend. LMS teraz posiada pełne wsparcie dla większości funkcji serwera PowerDNS. Ma pełnie wsparcie dla domen typu: master, slave i native. Na liście domen przedstawione są podstawowe informacje o zdefiniowanych domenach jak nazwa, typ, właściciel. Możliwe jest dowolne sortowanie listy poprzez kliknięcie nazwy kolumny lub poprzez pierwszą literę nazwy domeny. Możliwa jest edycja podstawowych danych domeny po wybraniu ikony [Edytuj]. Zaawansowana edycja rekordów domeny odbywa się poprzez wybranie ikony [Informacje] a następnie [Rekordy]. Możliwa wtedy jest pełna konfiguracja wszystkich rekordów opisujących daną domenę. Każda zmiana rekordu zapisana w bazie danych LMS np.: edycja, dodanie lub usunięcie rekordu automatycznie zwiększa licznik domeny o 1. Każda zmiana jest także automatycznie dostrzegana przez serwer PowerDNS. Aby taka wspópraca była możliwa należy w bazie danych LMS założyć dodatkowego użytkownika z uprawieniami SELECT, INSERT, UPDATE, DELETE dla tabel domains, records oraz SELECT dla tabeli supermaster.

3.9.6. Nowa domena

Dane domeny zawierają nazwę, opis, typ (master, slave, native), adres ip serwera www, adres ip serwera pocztowego, adres ip głównego serwera nazw (jeśli wybrano typ slave) i inne parametry, których wartości domyślne ustawione są w sekcji [zones]. Domena może zostać przypisana do klienta.

3.9.7. Szukaj

Wyszukiwanie kont, aliasów i domen według zadanych kryteriów.

3.9.8. Przykłady

Poniżej opisano sposób intergracji LMS z serwerem PowerDNS.

Przykład 3-1. Domeny. Konfiguracja PowerDNS.

Przygotowanie bazy danych na której działa LMS do współpracy z serwerem PowerDNS.  

Dodajemy użytkownika powerdns o uprawnieniach ograniczonych do tabel domains i records.

GRANT SELECT, INSERT, UPDATE, DELETE ON lms.domains TO 'powerdns'@'adres-serwera-dns' IDENTIFIED BY 'hasło';
GRANT SELECT, INSERT, UPDATE, DELETE ON lms.records TO 'powerdns'@'adres-serwera-dns' IDENTIFIED BY 'hasło';

Instalujemy pakiety: pdns, pdns-backend, pdns-recursor.

W dystrybucjach Centos, Fedora, RedHat:

yum install pdns pdns-backend pdns-recursor

Edytujemy plik /etc/pdns/pdns.conf dodając:

launch=gmysql
gmysql-dbname=lms #wpisz właściwą nazwę bazy danych na której pracuje lms
gmysql-host=adres-serwera-sql #podaj adres ip lub nazwę serwera na którym pracuje bazy danych
gmysql-password=hasło
gmysql-user=powerdns
master=yes 
slave=yes
recursor=127.0.0.1:5300
allow-recursion=127.0.0.0/8, 192.168.0.1/24 

Gdzie 192.168.0.1 to przykładowa sieć. Po przecinku należy dodać własne sieci z których
serwer ma obsługiwać zapytania rekurencyjne.

Edytujemy plik /etc/pdns-recursor/recursor.conf	dodając:

allow-from=127.0.0.0/8 
local-address=127.0.0.1
local-port=5300

Następnie:

chkconfig --levels 235 pdns-recursor on
chkconfig --levels 235 pdns on

service pdns-recursor start
service pdns start

Na Debianie:

apt-get install pdns-server pdns-backend-mysql pdns-recursor

Edytujemy plik  /etc/powerdns/pdns.conf dodając:

launch=gmysql

Edytujemy /etc/powerdns/pdns.d/pdns.local dodając: 

gmysql-dbname=lms #wpisz właściwą nazwę bazy danych na której pracuje lms
gmysql-host=adres-serwera-sql #podaj adres ip lub nazwę serwera na którym pracuje bazy danych
gmysql-password=hasło
gmysql-user=powerdns
master=yes 
slave=yes

Edytujemy plik /etc/powerdns/recursor.conf	dodając:

allow-from=127.0.0.0/8 
local-address=127.0.0.1
local-port=5300

Następnie 

/etc/init.d/pdns start
/etc/init.d/pdns-recursor start

Poniższy listing zawiera istotne fragmenty pliku konfiguracyjnego demona proftpd (w wersji 1.2.10) umożliwiający przechowywanie danych o kontach ftp w bazie LMSa. Przykład zawiera konfigurację dla bazy danych PostgreSQL, w komentarzach podano rozwiązania dla MySQLa:

Przykład 3-2. Hosting. Konfiguracja proftpd.

  ServerName	"LMS FTP Server"
  
  #nazwa_bazy@host:port klient hasło
  SQLConnectInfo lms@localhost:5432 lms mypassword
  
  SQLAuthTypes Crypt Plaintext
  SQLUserInfo passwd login password uid NULL home NULL
  RequireValidShell off
  SQLAuthenticate users
  
  # utworzenie katalogu domowego gdy nie istnieje
  SQLHomedirOnDemand on
  
  # komunikat przy logowaniu
  SQLShowInfo PASS "230" "Last login: %{getlastlogin}"
  SQLLog PASS setlastlogin
  
  # SQLNamedQuery getlastlogin SELECT "CASE lastlogin WHEN 0 THEN '' ELSE FROM_UNIXTIME(lastlogin) END FROM passwd WHERE login='%u'"
  # SQLNamedQuery setlastlogin UPDATE "lastlogin=UNIX_TIMESTAMP() WHERE login='%u'" passwd 
  SQLNamedQuery getlastlogin SELECT "CASE lastlogin WHEN 0 THEN '' ELSE lastlogin::abstime::timestamp::text END FROM passwd WHERE login='%u'"
  SQLNamedQuery setlastlogin UPDATE "lastlogin=EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)) WHERE login='%u'" passwd
  
  # Sprawdzamy datę ważności konta oraz ograniczamy szukanie do kont ftp
  # SQLUserWhereClause "type & 8 = 8 AND (expdate = 0 OR expdate > UNIX_TIMESTAMP())"
  SQLUserWhereClause "type & 8 = 8 AND (expdate = 0 OR expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))"

W kolejnym przykładzie przedstawimy jak skonfigurować serwer Postfix 2.1.1 oraz Cyrus-SASL 2.1.19, Courier-IMAP/POP3 3.0.4, aby korzystały z bazy danych LMSa. LMS'owe konta będą kontami wirtualnymi, a poczta przechowywana będzie w formacie Maildir.

Ponieważ hasła w LMS'ie są szyfrowane, wymagane jest zainstalowanie SASL'a z łatą pozwalającą na to. W komentarzach podano wartości opcji charakterystycznych dla bazy MySQL. Listing zawiera tylko opcje bezpośrednio związane z bazą danych:

Przykład 3-3. Konta. Konfiguracja serwera pocztowego (postfix+sasl+courier).

# Plik smtpd.conf (Cyrus-SASL):

pwcheck_method: auxprop
password_format: crypt
mech_list: login plain
sql_user: lms
sql_passwd: hasło
sql_hostnames: localhost
sql_database: lms
# MySQL
#sql_engine: mysql
#sql_select: SELECT p.password FROM passwd p, domains d WHERE p.domainid = d.id
#       AND p.login='%u' AND d.name ='%r' AND p.type & 2 = 2 
#	AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP())
# PostgreSQL
sql_engine: pgsql
sql_select: SELECT p.password FROM passwd p, domains d WHERE p.domainid = d.id
	AND p.login='%u' AND d.name ='%r' AND p.type & 2 = 2 
	AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))

# authpgsqlrc (lub authmysqlrc) (Courier):

# użytkownik postfix (właściciel katalogu z pocztą)
#MYSQL_UID_FIELD '1004'
PGSQL_UID_FIELD '1004'
# grupa postfix (właściciel katalogu z pocztą)
#MYSQL_GID_FIELD '1004'
PGSQL_GID_FIELD '1004'
#MYSQL_PORT		3306
PGSQL_PORT		5432
#MYSQL_USERNAME		lms
PGSQL_USERNAME		lms
#MYSQL_PASSWORD		hasło
PGSQL_PASSWORD		hasło
#MYSQL_DATABASE		lms
PGSQL_DATABASE		lms
#MYSQL_SELECT_CLAUSE SELECT p.login, \
#       p.password, '', 104, 104, '/var/spool/mail/virtual', \
#       CONCAT(d.name,'/', p.login, '/'), '', p.login, '' \
#       FROM passwd p, domains d WHERE p.domainid = d.id \
#       AND p.login = '$(local_part)' AND d.name = '$(domain)' \
#       AND p.type & 2 = 2 AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP())
PGSQL_SELECT_CLAUSE SELECT p.login, \
        p.password, '', 104, 104, '/var/spool/mail/virtual', \
        d.name || '/' || p.login ||'/', '', p.login, '' \
        FROM passwd p, domains d WHERE p.domainid = d.id 
        AND p.login = '$(local_part)' AND d.name = '$(domain)' \
        AND p.type & 2 = 2 \
        AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))

# main.cf (Postfix):

virtual_mailbox_base = /var/spool/mail/virtual
virtual_mailbox_domains = pgsql:/etc/postfix/virtual_domains_maps.cf
virtual_mailbox_maps = pgsql:/etc/postfix/virtual_mailbox_maps.cf
virtual_alias_maps = pgsql:/etc/postfix/virtual_alias_maps.cf
recipient_bcc_maps = pgsql:/etc/postfix/recipient_bcc_maps.cf

# virtual_domains_maps.cf (Postfix):

user = lms
password = hasło
hosts = localhost
dbname = lms
#pgSQL i MySQL
query = SELECT name FROM domains WHERE name = '%s'

# virtual_mailbox_maps.cf (Postfix):

user = lms
password = hasło
hosts = localhost
dbname = lms

# MySQL
#query = SELECT CONCAT(d.name,'/', p.login, '/') 
#	FROM passwd p, domains d WHERE p.domainid = d.id
#	AND p.login = '%u' AND d.name = '%d' 
#	AND p.type & 2 = 2 AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP())
# PostgresSQL
query = SELECT d.name || '/' || p.login || '/' 
	FROM passwd p, domains d WHERE p.domainid = d.id
        AND p.login = '%u' AND d.name = '%d' 
        AND p.type & 2 = 2 
        AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))

# virtual_alias_maps.cf (Postfix):

user = lms
password = hasło
hosts = localhost
dbname = lms
# MySQL
#query = SELECT p.mail_forward
#	FROM passwd p
#	JOIN domains d ON (p.domainid = d.id)
#	WHERE p.login = '%u' AND d.name = '%d'
#		AND p.type & 2 = 2 AND p.mail_forward != ''
#		AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP())
#	UNION
#       SELECT CASE WHEN aa.mail_forward != '' THEN aa.mail_forward ELSE CONCAT(p.login, '@', pd.name) END
#	FROM aliases a
#	JOIN domains ad ON (a.domainid = ad.id)
#	JOIN aliasassignments aa ON (aa.aliasid = a.id)
#	LEFT JOIN passwd p ON (aa.accountid = p.id AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP()))
#	LEFT JOIN domains pd ON (p.domainid = pd.id)
#	WHERE a.login = '%u' AND ad.name = '%d'
#		AND (aa.mail_forward != '' OR p.id IS NOT NULL)
# PostgreSQL	
query = SELECT p.mail_forward
	FROM passwd p
	JOIN domains d ON (p.domainid = d.id)
	WHERE p.login = '%u' AND d.name = '%d'
		AND p.type & 2 = 2 AND p.mail_forward != ''
		AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))
	UNION
	SELECT CASE WHEN aa.mail_forward != '' THEN aa.mail_forward ELSE p.login || '@' || pd.name END
	FROM aliases a
	JOIN domains ad ON (a.domainid = ad.id)
	JOIN aliasassignments aa ON (aa.aliasid = a.id)
	LEFT JOIN passwd p ON (aa.accountid = p.id
		AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0))))
	LEFT JOIN domains pd ON (p.domainid = pd.id)
	WHERE a.login = '%u' AND ad.name = '%d'
		AND (aa.mail_forward != '' OR p.id IS NOT NULL)

# recipient_bcc_maps.cf (Postfix):

user = lms
password = hasło
hosts = localhost
dbname = lms
# MySQL
#query = SELECT p.mail_bcc FROM passwd p, domains d 
#	WHERE p.domainid = d.id
#	    AND p.login = '%u' AND d.name = '%d'
#		AND p.type & 2 = 2
#		AND p.mail_bcc != ''
#		AND (p.expdate = 0 OR p.expdate > UNIX_TIMESTAMP())
# PostgreSQL
query = SELECT p.mail_bcc FROM passwd p, domains d 
	WHERE p.domainid = d.id
	        AND p.login = '%u' AND d.name = '%d'
		AND p.type & 2 = 2
		AND p.mail_bcc != ''
		AND (p.expdate = 0 OR p.expdate > EXTRACT(EPOCH FROM CURRENT_TIMESTAMP(0)))
					

Następny przykład podesłany przez bart'a przedstawia instalację i konfigurację serwera pure-ftpd w dystrybucji Gentoo z wykorzystaniem bazy danych MySQL.

Przykład 3-4. Konta. Konfiguracja pure-ftpd.

No to zaczynamy od instalacji serwera pure-ftpd. Pod Gentoo wygląda to tak:

bart # emerge pure-ftpd -av
These are the packages that I would merge, in order:
Calculating dependencies ...done!
[ebuild   R   ] net-ftp/pure-ftpd-1.0.20-r1  -caps -ldap +mysql +pam -postgres +ssl +vchroot 459 kB
Total size of downloads: 459 kB
Co do innych systemów to każdy chyba wie jak się instaluje pakiety w swoim systemie, a jeżeli nie to pozostaje kompilacja ze źródeł. Po zainstalowaniu przechodzimy do stworzenia pliku, który będzie odpowiadał za łączenie się z bazą LMS'a. Tworzymy plik /etc/pureftpd-mysql.conf, który to powinien zawierać minimum:
MYSQLServer     localhost (adres serwera bazy danych - domyślnie 'localhost')
MYSQLPort       3306 (port na którym działa serwer MySql - domyślnie '3306')
MYSQLSocket     /var/run/mysqld/mysqld.sock (
MYSQLUser       lms (nazwa usera z dostępem do bazy)
MYSQLPassword   hasło (tutaj należy podać hasło)
MYSQLDatabase   lms (nazwa bazy danych)
MYSQLCrypt      crypt (sposób przechowywania haseł)
MYSQLGetPW      SELECT password FROM passwd WHERE login="\L" (pobieranie hasła dla usera)
MYSQLGetUID     SELECT uid FROM passwd WHERE login="\L" (pobieranie uid dla usera)
MYSQLGetGID     SELECT gid FROM passwd WHERE login="\L" (pobieranie gid dla usera)
MYSQLGetDir     SELECT home FROM passwd WHERE login="\L" (pobieranie nazwy katalogu domowego dla usera)
MySQLGetQTASZ   SELECT quota_ftp FROM passwd WHERE login="\L" (quota czyli pojemność konta w MB - podając w lms-ui 10 oznacza to pojemność 10MB)
Teraz pozostaje nam już tylko konfiguracja serwera pure-ftpd. (w gentoo plik konfiguracyjny mieści się w /etc/conf.d/pure-ftpd) a więc:
## Najpierw odkomentujmy tę linię, ponieważ inaczej serwer nie będzie chciał wystartować
IS_CONFIGURED="yes"
## Tutaj podajemy adres naszego serwera i port na którym ma nasłuchiwać
SERVER="-S www.nasza.domena.pl,21"
## Określamy ilość jednoczesnych połączeń do serwera oraz ilość połączeń z tego samego IP
## To już chyba każdy według potrzeb
MAX_CONN="-c 50"
MAX_CONN_IP="-C 2"
## Startujemy daemona w tle
DAEMON="-B"
## Ustalamy procentową zajętość dysku/partycji kiedy serwer powinien przestać zezwalać na przyjmowanie danych
DISK_FULL="-k 90%"
## Jeżeli serwer jest za NATem odkomentuj tę linię
#USE_NAT="-N"
## Autoryzacja ma być pobierana z bazy LMS'a - podajemy ścieżkę do stworzonego przez nas wcześniej pliku
AUTH="-l mysql:/etc/pureftpd-mysql.conf"
## Pozostałe opcje w moim wypadku są takie
MISC_OTHER="-A -x -j"