Author: Gabriel Rüeck

FTP

Als effizientes Protokoll zum Austausch von Binärdaten ist FTP noch immer die beste Lösung. Deshalb läuft auch auf dem Caipirinha-Server ein FTP-Server. Aus Sicherheitsgründen wird allerdings nur anonymous ftp angeboten, so dass kein Benutzer auf die Idee kommt, seinen Usernamen und sein Passwort über eine ungeschützte Internet-Verbindung zu schicken. Auf der anderen Seite muss natürlich auch vermieden werden, dass durch Unachtsamkeit ein für alle offener Dateiaustausch-Server entsteht, auf dem dann wildfremde Benutzer ihre Audio- und Videodateien verteilen.

Deshalb wird eine Dateistruktur erstellt, die folgende Vorgehensweisen erlaubt:

Um die Ordnerstruktur anzulegen, wird zunächst in /home ein Ordner ftp mit folgendem Eigentümer und Berechtigung angelegt:

drwxr-xr-x  root  root     ftp

Das Verzeichnis wird nämlich das Home-Verzeichnis des Benutzers ftp werden. Es soll dennoch nicht dem Benutzer ftp, sondern root gehören, weil sonst jeder, der sich mit dem FTP-Server verbindet, eine x-beliebige Datei in diesem Verzeichnis ablegen kann.

Danach wird in /home/ftp diese Struktur angelegt:

-rw-r--r--  root  root     .banner
d--xrwsrwx  ftp   users    download
-rw-r--r--  root  root     readme.txt
d-wxrwsr-x  ftp   users    upload

.banner ist dabei eine Textdatei, welche Informationen über den FTP-Server enthält, die dann angezeigt werden, wenn sich ein Benutzer über ein Shell-basiertes FTP-Programm am Server anmeldet. readme.txt wird angezeigt, falls der Benutzer sich über einen Browser mit ftp://caipirinha.homelinux.org/ verbindet. Im Prinzip sollten .banner und readme.txt den gleichen Inhalt haben und die Funktionsweise des FTP-Servers erläutern. Beide Dateien gehören dem Benutzer root, so dass sie nicht durch den FTP-Server selbst verändert werden können.

Der Ordner download ist für die Gruppe users und für others beschreibbar, so dass diese Gruppen dort Dateien ablegen können. Im Prinzip reicht es aus, wenn er für die Gruppe users zugänglich ist. Hier beim Caipirinha-Server wurde er nur deswegen noch für die Gruppe others zugänglich gemacht, damit PHP-Skripte Dateien erzeugen und über den FTP-Server zum Download anbieten können. Da aber im Allgemeinen PHP-Skripte von Apache ausgeführt werden, laufen diese unter der Kennung wwwrun:www, und deswegen muss der Ordner download für others zugänglich sein. Der Benutzer ftp darf lediglich in diesen Ordner verzweigen, nicht aber dessen Inhalt lesen. Damit erreicht man, dass der Dateinamen bekannt sein muss, damit die Datei herunter geladen werden kann. Bei ausreichend kryptischen Dateinamen stellt dies einen einfachen, wenn auch nicht sicheren Schutz vor einem unberechtigten Download dar.

Der Ordner upload ist sowohl für den Benutzer ftp als auch für die Grupper users beschreibbar, für others lediglich lesbar. Der Benutzer ftp kann lediglich in den Ordner schreiben, aber nicht daraus lesen, weil sonst jemand unzulässigerweise einen Dateiaustausch-Server aufsetzen könnte. Die Gruppe users hat Schreibrechte, so dass ein Benutzer eine hochgeladene Datei nach der Verarbeitung löschen kann. others haben Leserechte, so dass beispielsweise PHP-Skripte über FTP hochgeladene Dateien verarbeiten können.

Auf dem Caipirinha-Server wird der FTP-Server pure-ftp eingesetzt, weil dieser mit nur einer Konfigurationsdatei auskommt und wenige Sicherheitsprobleme bereitet. Zur Installation von pure-ftp wird so vorgegangen:

  • Das Paket pure-ftpd installieren.
  • Die Ordnerstruktur aufsetzen, so wie sie oben beschrieben worden ist.
  • Die Konfigurationsdatei /etc/pure-ftpd/pure-ftpd.conf anpassen, so wie es im unten stehenden Listing dargestellt ist.
  • Nun muss für den Benutzer ftp noch das Home-Verzeichnis auf /home/ftp umgestellt werden. Die Login-Shell sollte aus Sicherheitsgründen deaktiviert werden, so dass für den Systembenutzer ftp letztendlich gilt:
ftp:x:40:49:FTP account:/home/ftp:/bin/false
  • pure-ftp with /etc/init.d/pure-ftpd starten.

Im Vergleich zur Original-Konfigurationsdatei /etc/pure-ftpd/pure-ftpd.conf haben sich die folgenden, selbsterklärenden Parameter geändert:

MaxClientsNumber            10
MaxClientsPerIP             10
AllowDotFiles               no
DisplayDotFiles             no
AnonymousOnly               yes
NoAnonymous                 no
SyslogFacility              none
MaxIdleTime                 15
LimitRecursion              2000 8
AnonymousCanCreateDirs      no
MaxLoad                     10
AntiWarez                   yes
ProhibitDotFilesWrite       yes
ProhibitDotFilesRead        yes
AutoRename                  yes
AnonymousCantUpload         no
AltLog                      clf:/var/log/pureftpd.log
NoChmod                     yes
KeepAllFiles                yes
MaxDiskUsage                90
NoRename                    yes
Posted in IT Tagged

MySQL

Einrichtung des MySQL-Servers auf dem Caipirinha-Server

MySQL ist für das vollständige Funktionieren eines LAMP-Systems eine der Grundvoraussetzungen. Auch auf dem Caipirinha-Server ist MySQL installiert, und zwar mit den Paketen:

  • mysql
  • mysql-administrator
  • mysql-client
  • mysql-gui-tools
  • mysql-query-browser
  • mysql-workbench

Auf dem Caipirinha-Server wird die Datenbank für folgende Dienste benutzt:

Die Konfiguration von MySQL erfolgt über die zentrale Konfigurationsdatei /etc/my.cnf, die hier in Auszügen wiedergegeben ist:

...
# The following options will be passed to all MySQL clients
[client]
 password    = your_password
 port        = 3306
 socket        = /var/lib/mysql/mysql.sock
# Here follows entries for some specific programs
# The MySQL server
[mysqld]
 port        = 3306
 socket        = /var/lib/mysql/mysql.sock
 skip-locking
 key_buffer = 16M
 max_allowed_packet = 16M
 table_cache = 64
 sort_buffer_size = 512K
 net_buffer_length = 8K
 read_buffer_size = 256K
 read_rnd_buffer_size = 512K
 myisam_sort_buffer_size = 8M
# New entries by Gabriel Rüeck
 datadir               = /home/public/Datenbanken
 log-error             = /var/log/mysql/errors.log
 log-slow-queries      = /var/log/mysql/slow_queries.log
 log-warnings
 ft_min_word_len       =  2
 ft_max_word_len       = 40
 ft_stopword_file      = ""
 long_query_time       = 1
# Set the Character Set of the server to UTF-8
 character_set_server     = utf8
 collation_server         = utf8_unicode_ci
 init_connect             ='SET character_set_connection=utf8; SET collation_connection=utf8_unicode_ci'
# Don't listen on a TCP/IP port at all. This can be a security enhancement,
# if all processes that need to connect to mysqld run on the same host.
# All interaction with mysqld must be made via Unix sockets or named pipes.
# Note that using this option without enabling named pipes on Windows
# (via the "enable-named-pipe" option) will render mysqld useless!
#  
# skip-networking
 …
# The safe_mysqld script
[safe_mysqld]
 log-error=/var/log/mysql/mysqld.log
[mysqldump]
 quick
 max_allowed_packet = 16M
[mysql]
 no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
# safe-updates
 …

Die Parameter key_buffer und max_allowed_packet wurden auf 16M eingestellt, um ganze Projektpläne für MS Project abspeichern zu können. Solche Projektpläne haben große binäre Blöcke, in denen MS Project proprietäre Daten speichert.

Mit dem Parameter datadir werden alle Datenbanken auf dem Caipirinha-Server in das Verzeichnis /home/public/Datenbanken gelegt, welches exklusiv dem Benutzer mysql:mysql gehört.

Die Parameter log-error, log-slow-queries und log-warnings legen fest, dass Fehler, Warnmeldungen und lange dauernde Abfragen festgehalten werden. Die beiden Fehlerdateien /var/log/mysql/errors.log und /var/log/mysql/slow_queries.log sollten regelmäßig überprüft werden. In der Datei /var/log/mysql/slow_queries.log werden SQL-Abfragen festgehalten, deren Abarbeitung unbotmäßig viel Rechenzeit in Anspruch nimmt. Eine häufige Ursache dafür sind nicht optimal strukturierte SQL-Abfragen, in denen Tabellen verknüpft werden. Eine alternative Verknüpfung mit einer JOIN LEFT-Syntax bewirkt meist Abhilfe.

Mit den Parametern ft_min_word_len und ft_max_word_len legt man fest, dass für die Volltextsuche ein Suchbegriff mindestens 2 und höchstens 40 Zeichen lang sein darf. Der leere Wert für ft_stopword_file schließlich deaktiviert die standardmäßige Stoppwortliste.

Mit dem Parameter long_query_time wird hier festgelegt, dass alle Abfragen, welche länger als 1s benötigen, als “zu lange” eingestuft werden.

Das Verzeichnis /var/log ist nur für den Benutzer root beschreibbar. Deshalb legt man dort ein Unterverzeichnis namens mysql an, so dass MySQL in diesem Unterverzeichnis alle Log-Dateien ablegen und diese auch rotieren kann. Dazu muss man nun noch als Benutzer root folgende Kommandos ausführen:

mkdir /var/log/mysql
chown mysql:mysql /var/log/mysql

Nach diesen Anpassungen wird MySQL mit /etc/init.d/mysql start gestartet.

Jetzt muss unbedingt ein Passwort fur den Benutzer root auf dem MySQL-Server vergeben werden, denn im Moment kann sich noch jeder Benutzer auf dem Caipirinha-Server mit dem MySQL-Server verbinden. Man beachte, dass der MySQL-Benutzer root nicht mit dem Systembenutzer root des Caipirinha-Servers identisch ist. MySQL hat seine eigenen Benutzer, und unter denen gibt es auch einen Superuser root. Mit mysqladmin –u root password geheimes_Passwort vergibt man das root-Passwort und verhindert dadurch automatisch, dass sich Benutzer am MySQL-Server ohne Passwort anmelden können. Das heisst, es obliegt nun dem MySQL-root, weitere MySQL-Benutzer einzurichten, wenn dies erforderlich ist. Das Einloggen auf dem MySQL-Server muss jetzt mit dem Befehl mysql –u Benutzer –p geheimes_Passwort geschehen. Man kann auch das Passwort weglassen, dann wird man beim Einloggen explizit danach gefragt.

MySQL hat seine eigene Sprache und Syntax, und an dieser Stelle sollen nur einige elementare Dinge vorgestellt werden.

Elementare MySQL-Befehle

Im einem nun folgenden Beispiel werden folgende Dinge gezeigt:

  • Ein Benutzer loggt sch als als MySQL-Benutzer root ein.
  • Der nun als root eingeloggte MySQL-Benutzer lässt sich alle Datenbanken anzeigen.
  • Dann wählt er die MySQL-Systemdatenbank mysql aus (welche schon bei der Installation eingerichtet wird).
  • Er lässt sich eine Übersicht aller Tabellen der Datenbank mysql geben.
  • Er lässt sich die Tabelle user näher beschreiben.
  • Aus der Tabelle user lässt er sich alle Benutzer anzeigen.
  • Danach loggt sich der MySQL-Benutzer root wieder aus.

Wie in der Literatur üblich, werden die MySQL-Befehle in Großbuchstaben geschrieben. Dies ist aber nicht notwendig.

caipirinha:~ # mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 25
Server version: 5.1.36 SUSE MySQL RPM

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| CCPM_Test          |
| GroupOffice        |
| PCBA               |
| Wiki               |
| coppermine         |
| mysql              |
| nonCCPM_Test       |
+--------------------+
8 rows in set (0.00 sec)

mysql> USE mysql;
Database changed
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_mysql           |
+---------------------------+
| columns_priv              |
| db                        |
| event                     |
| func                      |
| general_log               |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| host                      |
| ndb_binlog_index          |
| plugin                    |
| proc                      |
| procs_priv                |
| servers                   |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+
23 rows in set (0.09 sec)

mysql> DESCRIBE user;
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field                 | Type                              | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host                  | char(60)                          | NO   | PRI |         |       |
| User                  | char(16)                          | NO   | PRI |         |       |
| Password              | char(41)                          | NO   |     |         |       |
| Select_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Insert_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Update_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Delete_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Create_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Drop_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Reload_priv           | enum('N','Y')                     | NO   |     | N       |       |
| Shutdown_priv         | enum('N','Y')                     | NO   |     | N       |       |
| Process_priv          | enum('N','Y')                     | NO   |     | N       |       |
| File_priv             | enum('N','Y')                     | NO   |     | N       |       |
| Grant_priv            | enum('N','Y')                     | NO   |     | N       |       |
| References_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Index_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Alter_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Show_db_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Super_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Create_tmp_table_priv | enum('N','Y')                     | NO   |     | N       |       |
| Lock_tables_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Execute_priv          | enum('N','Y')                     | NO   |     | N       |       |
| Repl_slave_priv       | enum('N','Y')                     | NO   |     | N       |       |
| Repl_client_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Create_view_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Show_view_priv        | enum('N','Y')                     | NO   |     | N       |       |
| Create_routine_priv   | enum('N','Y')                     | NO   |     | N       |       |
| Alter_routine_priv    | enum('N','Y')                     | NO   |     | N       |       |
| Create_user_priv      | enum('N','Y')                     | NO   |     | N       |       |
| Event_priv            | enum('N','Y')                     | NO   |     | N       |       |
| Trigger_priv          | enum('N','Y')                     | NO   |     | N       |       |
| ssl_type              | enum('','ANY','X509','SPECIFIED') | NO   |     |         |       |
| ssl_cipher            | blob                              | NO   |     | NULL    |       |
| x509_issuer           | blob                              | NO   |     | NULL    |       |
| x509_subject          | blob                              | NO   |     | NULL    |       |
| max_questions         | int(11) unsigned                  | NO   |     | 0       |       |
| max_updates           | int(11) unsigned                  | NO   |     | 0       |       |
| max_connections       | int(11) unsigned                  | NO   |     | 0       |       |
| max_user_connections  | int(11) unsigned                  | NO   |     | 0       |       |
+-----------------------+-----------------------------------+------+-----+---------+-------+
39 rows in set (0.00 sec)

mysql> SELECT Host,User FROM user;
+-----------+-----------------+
| Host      | User            |
+-----------+-----------------+
| %         | gabriel         |
| localhost | cms_user        |
| localhost | coppermine_user |
| localhost | go_user         |
| localhost | lp_mis          |
| localhost | mis             |
| localhost | root            |
+-----------+-----------------+
7 rows in set (0.02 sec)

mysql> QUIT;
Bye
caipirinha:~ #

Man erkennt mehrere Benutzer, von denen sich alle ausser gabriel nur auf dem Caipirinha-Server selbst einloggen können und sich nicht von einer entfernten Maschine aus über Port 3306 verbinden können. Aus Sicherheitsgründen ist es grundsätzlich zu empfehlen, die Benutzerrechte so weit wie möglich einzuschränken. In diesem Fall darf sich nur der Benutzer gabriel auch von entfernten MySQL-Clients über Port 3306 mit dem MySQL-Server auf Caipirinha verbinden.

Im nächsten Beispiel wird ein neuer Benutzer test mit dem geheimen Passwort abc’ angelegt. Er bekommt uneingeschränkte Zugriffsrechte auf die Datenbank Wiki. Diese beiden Schritte kann man gleich in einem Schritt zusammen fassen, was hier auch so gemacht wird. Dann schauen wir uns die gesetzten Rechte an und löschen den Benutzer wieder.

mysql> GRANT ALL ON Wiki.* TO 'test' IDENTIFIED BY 'abc';
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW GRANTS FOR 'test';
+-----------------------------------------------------------------------------------------------------+
| Grants for test@%                                                                                   |
+-----------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'test'@'%' IDENTIFIED BY PASSWORD '*0D3CED9BEC10A777AEC23CCC353A8C08A633045E' |
| GRANT ALL PRIVILEGES ON `Wiki`.* TO 'test'@'%'                                                      |
+-----------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> DROP USER 'test';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Hier wird ersichtlich, dass durch das kombinierte Anlegen des Benutzers eigentlich gleich zweimal Benutzerrechte vergeben werden. Zum einen erhält der Benutzer überhaupt Zugangsrechnte zum MySQL-Server. Und zum zweiten erhält er dann uneingeschränkte Zugriffsrechte auf die Datenbank Wiki. Auf andere Datenbanken kann er nicht zugreifen. Man sieht außerdem, dass das Passwort verschlüsselt abgelegt wird.

Backup der Datenbanken

Alle Datenbanken müssen natürlich regelmäßig gesichert werden. Dazu gibt es die beiden Programme mysqldump und mysqlhotcopy, die beide ihre Vor- und Nachteile haben. Auf dem Caipirinha-Server habe ich mich für mysqldump entschieden. mysqldump erzeugt komplette SQL-Sequenzen in derselben Reihenfolge, in der man sie eintippen müsste, wenn man die entsprechende Datenbank neu erstellen müsste.

Das Backup für den MySQL-Server ist inzwischen im allgemeinen Backup-Skript integriert worden. Mit den folgenden Befehlen kann man in einer Shell beispielsweise alle Datenbanken in einem mit gzip komprimierten Format sichern:

readonly MYSQL_USERNAME=user
readonly MYSQL_PASSWORD=geheimes_passwort
DATABASE_LIST=$(mysql -e 'show databases' -u$MYSQL_USERNAME -p$MYSQL_PASSWORD)
DATABASE_LIST=$(echo $DATABASE_LIST | cut -d " " -f2-)
for DATABASE in $DATABASE_LIST
    do mysqldump -BC --hex-blob -u$MYSQL_USERNAME -p$MYSQL_PASSWORD $DATABASE | gzip -n9 > /backup/$DATABASE.sql.gz
done

Zum Wiederherstellen muss man dann lediglich die von mysqldump erzeugte SQL-Datei wieder mit gunzip entpacken und mit dem Befehl mysql -uroot -p geheimes Passwort < backup_datei.sql einlesen.

Replikation von Datenbanken

Mit einer Replikation kann man den Datenbestand eines Slave Servers mit dem Datenbestand eines Master Servers synchronisieren. Dadurch kann man folgende Vorteile erreichen:

  • Lastverteilung bei stark frequentierten Systemen, indem Schreibzugriffe auf den Master Server und Lese-Zugriffe auf einen oder mehrere Slave Server verlegt werden
  • Eine Art Backup-Lösung, bei der man bei Ausfall des Master Servers durch Modifikation einiger Dateien relativ schnell auf den laufen Slave Server umschalten kann (vorausgesetzt, die Applikation unterstützt das)
  • Daten-Synchronisation mit entfernten Standorten

Eine solche Replikation setzt also mindestens 2 MySQL-Server voraus, mit unterschiedlichen Server IDs. Die Versionsnummern der MySQL-Server sollten idealerweise die gleichen sein, ansonsten sollte der Slave Server stets die höhere Versionsnummer als der Master Server haben.

Auf dem Master Server wird die Konfigurationsdatei /etc/my.cnf so modifiziert:

# Replication Master Server (default)
# binary logging is required for replication
log-bin         = /var/log/mysql/binlog
max_binlog_size = 256M

# required unique id between 1 and 2^32 - 1
# defaults to 1 if master-host is not set
# but will not function as a master if omitted
server-id = 1

Außerdem wird im MySQL Master Server ein Replikationsbenutzer angelegt, und zwar mit:

mysql> GRANT REPLICATION SLAVE ON *.* TO 'Replikationsbenutzer' IDENTIFIED BY 'Replikationspasswort';

Replikationsbenutzer und Replikationspasswort müssen natürlich einen sinnvollen Benutzernamen und ein sinnvolles Passwort ersetzt werden. Man kann den Replikationsbenutzer auch einschränken, beispielsweise auf 'Replikationsbenutzer'@'10.130.25.110', wenn der Slave-Server auf einer Maschine mit der statischen IP-Adresse 10.130.25.110 läuft. Das erhöht die Sicherheit etwas. Ansonsten hilft nur ein möglichst kompliziertes Passwort.

Jetzt muss man mit /etc/init.d/mysql restart den Master Server neu starten. Danach nimmt man ein Backup des Datenbestands des Master Servers vor und spielt dieses Backup im Slave Server ein. Idealerweise erfolgt daher der Neustart des Master Servers und das Anfertigen des Backups zu einer Zeit, da möglichst wenig Datenzugriffe stattfinden. Ansonsten bietet die MySQL-Dokumentation [1] noch Hinweise, wie man Datenbanken gegen Schreibzugriffe sperren kann, so dass konsistente Datenbestände gesichert werden können.

Jetzt (nach dem Einspielen des Backups) muss man die Konfigurationsdatei /etc/my.cnf des Slave Servers anpassen, beispielsweise auf:

# Replication Slave (comment out master section to use this)
#
# To configure this host as a replication slave, you can choose between
# two methods :
#
...
# required unique id between 2 and 2^32 - 1
# (and different from the master)
# defaults to 2 if master-host is set
# but will not function as a slave if omitted
server-id       = 2
master-host     = 172.16.0.1
master-user     = "Replikationsbenutzer"
master-password = "Replikationspasswort"
master-port     = 3306
report_host     = "caipirinha.homelinux.org"
report_port     = 3306

# binary logging - not required for slaves, but recommended
#log-bin                 = /var/log/mysql/binlog
#max_binlog_size         = 256M
max_relay_log_size      = 256M
replicate-wild-do-table = GroupOffice.%
replicate-wild-do-table = Wiki.%
replicate-wild-do-table = coppermine.%

In diesem Beispiel wird mit dem Parameter max_relay_log_size die maximale Größe der Relay-Log-Datei des Slave Servers auf 256MB begrenzt. Die Relay-Log-Dateien sind die “Slave”-Version der binären Log-Dateien des “Masters”. Der Slave Server hält dort fest, welche Änderungen des Master Servers er bereits nachvollzogen hat.

Mit dem Parameter replicate-wild-do-table kann man die Namen einer oder mehrerer Tabellen festlegen, die repliziert werden sollen. Es ist hierbei möglich, alle Tabellen einer Datenbank auszuwählen, indem man den Datenbanknamen, gefolgt von .% angibt. Man kann den Parameter auch komplett weglassen, dann werden alle Datenbanken repliziert. Ich halte es dann für sinnvoll, Namen anzugeben, wenn auf dem Slave Server noch andere Datenbanken liegen, die nicht aus einer Replikation eines Master Servers stammen, sondern die lokal verwaltet werden.

Nun muss der Slave Server mit der neuen Konfiguration gestartet werden, allerdings, nachdem die zuvor gesicherten Datenbanken des MAster Servers eingespielt worden sind.

Es ist nicht schlimm, wenn das Aufsetzen des Slave Servers etwas Zeit braucht, denn der Master Server schreibt ja inzwischen alle Änderungen in die binäre Log-Datei, und der Slave-Server wird sich dann ab dem Einspielen der Datenbanken alle Änderungen vom Master Server holen diese nachvollziehen.

In MySQL kann man sich auf dem Master Server den Status der Replikation mit folgenden Befehlen anzeigen lassen:

mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| binlog.000001 |    10941 |              |                  |
+---------------+----------+--------------+------------------+
1 row in set (0.00 sec)

mysql> SHOW PROCESSLIST;
+----+--------+------------------+------+-------------+------+----------------------------------------------------------------+------------------+
| Id | User   | Host             | db   | Command     | Time | State                                                          | Info             |
+----+--------+------------------+------+-------------+------+----------------------------------------------------------------+------------------+
|  8 | sombra | 172.16.0.6:58988 | NULL | Binlog Dump |  157 | Has sent all binlog to slave; waiting for binlog to be updated | NULL             |
| 24 | root   | localhost        | NULL | Query       |    0 | NULL                                                           | SHOW PROCESSLIST |
+----+--------+------------------+------+-------------+------+----------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)

mysql> SHOW SLAVE HOSTS;
+-----------+--------------------------+------+-------------------+-----------+
| Server_id | Host                     | Port | Rpl_recovery_rank | Master_id |
+-----------+--------------------------+------+-------------------+-----------+
|         2 | caipirinha.homelinux.org | 3306 |                 0 |         1 |
+-----------+--------------------------+------+-------------------+-----------+
1 row in set (0.00 sec)

Hier sieht man, dass ein Replikationsbenutzer namens sombra auf dem Master Server eingeloggt ist. Auf dem Slave Server kann man sich analog dazu den Status der Replikation mit folgenden Befehlen anzeigen lassen:

mysql> SHOW SLAVE STATUS\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.0.1
                  Master_User: sombra
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 10941
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 11083
        Relay_Master_Log_File: binlog.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: GroupOffice,Wiki,coppermine
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 10941
              Relay_Log_Space: 11239
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
1 row in set (0.00 sec)

ERROR:
No query specified

mysql> SHOW PROCESSLIST;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                                 | Info             |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |  174 | Waiting for master to send event                                      | NULL             |
|  2 | system user |           | NULL | Connect |   44 | Has read all relay log; waiting for the slave I/O thread to update it | NULL             |
|  4 | root        | localhost | NULL | Query   |    0 | NULL                                                                  | SHOW PROCESSLIST |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

Hier sieht man, dass der Slave Server derzeit auf Änderungen durch den Master Server wartet.

Der Slave Server legt im Datenbank-Verzeichnis eine Datei namens master.info (Textdatei) an, in welcher wichtige Replikationsparameter aus der Konfigurationsdatei /etc/my.cnf des Slave Servers abgelegt werden. Existiert diese Datei, dann werden die Replikationsparameter beim Start des Slave Servers nicht mehr aus /etc/my.cnf gelesen, selbst wenn sie dort verändert worden sind. Will man also Änderungen wirksam machen, muss man entweder master.info löschen oder die ab MySQL 6 empfohlene Syntax CHANGE MASTER TO... im MySQL-Interface anwenden.

Ausführliche Informationen zum Thema Replikation finden sich ferner in [2].

MRTG

Prozessor-Auslastung auf dem Caipirinha-Server
Prozessor-Auslastung auf dem Caipirinha-Server
Netzwerk-Verkehr auf dem Caipirinha-Server
Netzwerk-Verkehr auf dem Caipirinha-Server

Mit dem Programm Multi Router Traffic Grapher (mrtg) lassen sich der zeitliche Verlauf von Netzwerkverkehr, CPU-Auslastung, Auslastung von Partitionen, etc. grafisch visualisieren. Dazu fragt das Programm periodisch eine oder mehrere Schnittstellen auf einem oder mehreren Netzknoten über SNMP ab. Mit Hilfe von Shell-Skripten sind aber darüber hinaus noch weitergehende Statistiken möglich [1]. David Guerrero hat in [2] eine verständliche Übersicht zum Thema SNMP und mrtg geschrieben. In der NET-SNMP Wiki sind ebenfalls zahlreiche Informationen enthalten.

Auf dem Caipirinha-Server werden aktuell folgende Statistiken bereit gestellt:

  • Netzwerkverkehr auf dem ADSL-Router [3]
  • Prozessorlast der Dual-Core CPU [4]
  • Auslastung der Partitionen /home und /backup [5]
  • Postfach-Größe der Benutzer gabriel und joselia [6]

Um mrtg einzurichten, muss man so vorgehen:

  • Der SNMP-Dienst muss auf den abzufragenden Netzknoten eingerichtet werden.
  • Ein Community-Name für den Lese-Zugriff muss auf den SNMP-Netzknoten festgelegt werden.
  • Das Paket mrtg muss auf dem Server installiert werden.
  • Die Konfigurationsdatei /etc/mrtg.conf muss entsprechend den darzustellenden Statistiken angepasst werden.
  • Eventuell müssen mit Hilfe eines cron-jobs Shell-Skripte ausgeführt werden.
  • In einem für den Apache-Server sichtbaren Bereich wird ein neues Unterverzeichnis eingerichtet und dem Benutzer des Webservers überschrieben. Im einfachsten Fall kann man das so machen:
mkdir /srv/www/htdocs/mrtg
chown wwwrun:www /srv/www/htdocs/mrtg

Hier ist die Konfigurationsdatei /etc/mrtg.conf des Caipirinha-Servers abgedruckt.

######################################################################
# MRTG Configuration File
# Gabriel Rüeck, 28-Apr-2010
######################################################################

Background[_]:  #ffffc8
Language:       german
Options[_]:     growright,integer,noinfo,nopercent
SnmpOptions:    timeout => 10, retries => 2
RunAsDaemon:    yes
WorkDir:        /srv/www/htdocs/mrtg

######################################################################
# System: caipirinha
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

#Target[caipirinha]: \eth0:public@caipirinha
#SetEnv[caipirinha]: MRTG_INT_IP="192.168.3.3" MRTG_INT_DESCR="eth0"
#MaxBytes[caipirinha]: 12500000
#Title[caipirinha]: Traffic Analysis for eth0 -- caipirinha
#PageTop[caipirinha]: <h1>Traffic Analysis for eth0 -- caipirinha</h1>
# <div id="sysdetails">
# <table>
# <tr>
# <td>System:</td>
# <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
# </tr>
# <tr>
# <td>Kontakt:</td>
# <td>"Gabriel Rüeck <gabriel@caipirinha.homelinux.org>"</td>
# </tr>
# <tr>
# <td>ifName:</td>
# <td>eth0</td>
# </tr>
# <tr>
# <td>Max Speed:</td>
# <td>12.5 MBytes/s</td>
# </tr>
# </table>
# </div>

######################################################################
# System: Arcor A800 Router
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

Target[router]:     12:public@192.168.3.1
SetEnv[router]:     MRTG_INT_IP="192.168.3.1" MRTG_INT_DESCR="PPPoE1"
MaxBytes[router]:   1000000
Title[router]:      Datenverkehr am ADSL-Router
YLegend[router]:    Bytes/s
PageTop[router]:    <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Datenverkehr am ADSL-Router</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small">
 <table>
 <tr>
 <td>System:</td>
 <td>ADSL Router in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################
# System: CAIPIRINHA Server
# Location: "Ostpreußendamm 18B, 12207 Berlin, Germany"
######################################################################

Target[cpu]:       .1.3.6.1.4.1.2021.11.50.0&.1.3.6.1.4.1.2021.11.50.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.52.0&.1.3.6.1.4.1.2021.11.52.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.51.0&.1.3.6.1.4.1.2021.11.51.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.54.0&.1.3.6.1.4.1.2021.11.54.0:public@caipirinha+
                   .1.3.6.1.4.1.2021.11.56.0&.1.3.6.1.4.1.2021.11.56.0:public@caipirinha
RouterUptime[cpu]: public@caipirinha
MaxBytes[cpu]:     200
Title[cpu]:        CPU-Auslastung auf CAIPIRINHA
Options[cpu]:      growright,integer,noinfo,noo,nopercent
Unscaled[cpu]:     ymwd
Suppress[cpu]:     ym
ShortLegend[cpu]:  %
YLegend[cpu]:      CPU Load
Legend1[cpu]:      Gesamt-Auslastung der Prozessor-Kerne
LegendI[cpu]:      CPU-Auslastung
PageTop[cpu]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">CPU-Auslastung</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################

Target[dsk]:       .1.3.6.1.4.1.2021.9.1.9.2&.1.3.6.1.4.1.2021.9.1.9.5:public@caipirinha
RouterUptime[dsk]: public@caipirinha
MaxBytes[dsk]:     100
kilo[dsk]:         1024
Title[dsk]:        Auslastung der Datenpartitionen auf CAIPIRINHA
Options[dsk]:      gauge,growright,integer,noinfo,nopercent
Unscaled[dsk]:     ymwd
Suppress[dsk]:     mwd
ShortLegend[dsk]:  %
YLegend[dsk]:      Disk Usage
Legend1[dsk]:      Auslastung der Partition /home
Legend2[dsk]:      Auslastung der Partition /backup
LegendI[dsk]:      /home
LegendO[dsk]:      /backup
PageTop[dsk]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Auslastung der Datenpartitionen</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>

######################################################################

Target[mail]:       .1.3.6.1.4.1.2021.8.1.101.1&.1.3.6.1.4.1.2021.8.1.101.2:public@caipirinha
MaxBytes[mail]:     10000000000
kilo[mail]:         1024
Title[mail]:        Postfach-Größe auf CAIPIRINHA
Options[mail]:      gauge,growright,integer,noinfo,nopercent
Unscaled[mail]:     none
Suppress[mail]:     mwd
ShortLegend[mail]:  B
YLegend[mail]:      Mail Folder Size
Legend1[mail]:      Postfach-Größe von Gabriel
Legend2[mail]:      Postfach-Größe von Josélia
LegendI[mail]:      gabriel
LegendO[mail]:      joselia
PageTop[mail]:     <h1 style="font-family:Arial,Verdana,sans-serif; font-size:big; color:green">Postfach-Größe auf CAIPIRINHA</h1>
 <div style="font-family:Arial,Verdana,sans-serif; font-size:small" id="sysdetails">
 <table>
 <tr>
 <td>System:</td>
 <td>caipirinha in "Ostpreußendamm 18B, 12207 Berlin, Germany"</td>
 </tr>
 <tr>
 <td>Kontakt:</td>
 <td><a href="mailto://gabriel@caipirinha.homelinux.org">Gabriel Rüeck</a></td>
 </tr>
 </table>
 </div>
Auslastung der Partitionen /home und /backup
Auslastung der Partitionen /home und /backup
Postfach-Größe
Postfach-Größe von gabriel und joselia

Diese Konfigurationsdatei enthält sechs Teile. Im ersten Teil werden verschiedene global gültige Einstellungen festgelegt. Der zweite (auskommentierte) Teil enthält eine Abfrage der eth0-Schnittstelle des Caipirinha-Servers, deren Statistiken momentan aber nicht mehr erstellt werden.

Der dritte Teil fragt die PPPoE-Schnittstelle an meinem ADSL-Router ab. Dabei handelt es sich um die sehr gut ausgestattete Easy-Box A800, einem WLAN-VoIP-Adapter von Vodafone [7]. Dieser ist SNMP-fähig, und nach einigem Tüfteln konnte ich die PPPoE-Schnittstelle als Interface #12 lokalisieren (snmpwalk -v2c -cpublic 192.168.3.1 .1.3.6.1.2.1.2.2.1.2). Deshalb ist im zweiten (und nicht auskommentierten) Teil der Konfigurationsdatei für den Parameter Target[router] das Argument 12:public@192.168.3.1 gesetzt worden. Natürlich muss man auch noch SNMP in der Easy-Box A800 aktivieren, damit alles zusammen spielt.

Der vierte Teil setzt die Prozessorlast aus mehreren Variablen zusammen; diesen Ansatz habe ich in einigen Foren gefunden. Mit den Befehlen snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.11 | fgrep "Cpu" kann man sich alle auf dem SNMP-Knoten verfügbare CPU-Variablen ausgeben lassen:

UCD-SNMP-MIB::ssCpuUser.0 = INTEGER: 15
UCD-SNMP-MIB::ssCpuSystem.0 = INTEGER: 3
UCD-SNMP-MIB::ssCpuIdle.0 = INTEGER: 5
UCD-SNMP-MIB::ssCpuRawUser.0 = Counter32: 74362304
UCD-SNMP-MIB::ssCpuRawNice.0 = Counter32: 13087145
UCD-SNMP-MIB::ssCpuRawSystem.0 = Counter32: 7511231
UCD-SNMP-MIB::ssCpuRawIdle.0 = Counter32: 150434264
UCD-SNMP-MIB::ssCpuRawWait.0 = Counter32: 3540187
UCD-SNMP-MIB::ssCpuRawKernel.0 = Counter32: 0
UCD-SNMP-MIB::ssCpuRawInterrupt.0 = Counter32: 193882
UCD-SNMP-MIB::ssCpuRawSoftIRQ.0 = Counter32: 332350

Eine Beschreibung der einzelnen Variablen gibt es in [8]. Da der Caipirinha-Server einen Zweikern-Prozessor hat, wurde MaxBytes auf 200 gesetzt. Alternativ hätte man die Summe der CPU-Variablen bei Target durch 2 teilen können und MaxBytes dann auf 100 setzen. Da es keinen Sinn macht, die Prozessorlast über einen ganzen Monat oder gar über ein ganzes Jahr zu visualisieren, werden diese beiden Statistiken unterdrückt (Suppress).

Der fünfte Teil visualisiert die Auslastung der Datenpartitionen /home und /backup über die SNMP-Variablen dskPercent.2 und dskPercent.5, die auf dem Caipirinha-Server eben diesen Partitionen entsprechen. Welche Partitionen welchen Variablen zugeordnet sind, kann man mit dem Befehl snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.9 herausfinden. In meinem Fall ergibt dies:

UCD-SNMP-MIB::dskIndex.1 = INTEGER: 1
UCD-SNMP-MIB::dskIndex.2 = INTEGER: 2
UCD-SNMP-MIB::dskIndex.3 = INTEGER: 3
UCD-SNMP-MIB::dskIndex.4 = INTEGER: 4
UCD-SNMP-MIB::dskIndex.5 = INTEGER: 5
UCD-SNMP-MIB::dskPath.1 = STRING: /
UCD-SNMP-MIB::dskPath.2 = STRING: /home
UCD-SNMP-MIB::dskPath.3 = STRING: /home/public/Video
UCD-SNMP-MIB::dskPath.4 = STRING: /var
UCD-SNMP-MIB::dskPath.5 = STRING: /backup
UCD-SNMP-MIB::dskDevice.1 = STRING: /dev/md0
UCD-SNMP-MIB::dskDevice.2 = STRING: /dev/mapper/cr_md2
UCD-SNMP-MIB::dskDevice.3 = STRING: /dev/md3
UCD-SNMP-MIB::dskDevice.4 = STRING: /dev/mapper/cr_md1
UCD-SNMP-MIB::dskDevice.5 = STRING: /dev/mapper/cr_sde1
...
UCD-SNMP-MIB::dskMinPercent.1 = INTEGER: 50
UCD-SNMP-MIB::dskMinPercent.2 = INTEGER: 10
UCD-SNMP-MIB::dskMinPercent.3 = INTEGER: 10
UCD-SNMP-MIB::dskMinPercent.4 = INTEGER: 20
UCD-SNMP-MIB::dskMinPercent.5 = INTEGER: 20
UCD-SNMP-MIB::dskTotal.1 = INTEGER: 51612944
UCD-SNMP-MIB::dskTotal.2 = INTEGER: 901563648
UCD-SNMP-MIB::dskTotal.3 = INTEGER: 1953388800
UCD-SNMP-MIB::dskTotal.4 = INTEGER: 8253744
UCD-SNMP-MIB::dskTotal.5 = INTEGER: 976628416
UCD-SNMP-MIB::dskAvail.1 = INTEGER: 40712692
UCD-SNMP-MIB::dskAvail.2 = INTEGER: 507764800
UCD-SNMP-MIB::dskAvail.3 = INTEGER: 165607280
UCD-SNMP-MIB::dskAvail.4 = INTEGER: 6885812
UCD-SNMP-MIB::dskAvail.5 = INTEGER: 232891056
UCD-SNMP-MIB::dskUsed.1 = INTEGER: 8278452
UCD-SNMP-MIB::dskUsed.2 = INTEGER: 348001984
UCD-SNMP-MIB::dskUsed.3 = INTEGER: 1787781632
UCD-SNMP-MIB::dskUsed.4 = INTEGER: 948664
UCD-SNMP-MIB::dskUsed.5 = INTEGER: 743737344
UCD-SNMP-MIB::dskPercent.1 = INTEGER: 17
UCD-SNMP-MIB::dskPercent.2 = INTEGER: 41
UCD-SNMP-MIB::dskPercent.3 = INTEGER: 92
UCD-SNMP-MIB::dskPercent.4 = INTEGER: 12
UCD-SNMP-MIB::dskPercent.5 = INTEGER: 76
...
UCD-SNMP-MIB::dskErrorFlag.1 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.2 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.3 = INTEGER: error(1)
UCD-SNMP-MIB::dskErrorFlag.4 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorFlag.5 = INTEGER: noError(0)
UCD-SNMP-MIB::dskErrorMsg.1 = STRING:
UCD-SNMP-MIB::dskErrorMsg.2 = STRING:
UCD-SNMP-MIB::dskErrorMsg.3 = STRING: /home/public/Video: less than 10% free (= 92%)
UCD-SNMP-MIB::dskErrorMsg.4 = STRING:
UCD-SNMP-MIB::dskErrorMsg.5 = STRING:

Hier macht es meiner Meinung nach nur Sinn, die Jahresgrafik darzustellen, denn man ist ja eher am langfristigen Trend interessiert. Deshalb werden hier alle anderen Statistiken unterdrückt (Suppress).

Der sechste Teil zeigt die Postfach-Größe der beiden Benutzer gabriel und joselia im Verzeichnis /home/public/Mail. Dazu wird durch das Auslesen der SNMP-Variablen extOutput.1 und extOutput.2 über den SNMP-Dienst ein Shell-Skript ausgeführt, welches die Postfach-Größe des jeweiligen Benutzers ermittelt. Hier macht es meiner Meinung nach ebenfalls nur Sinn, die Jahresgrafik, also den langfristigen Trend, darzustellen. Deshalb werden auch hier alle anderen Statistiken unterdrückt.

SNMP-Konfiguration der Easy-Box A800
SNMP-Konfiguration der Easy-Box A800

Mit snmpwalk -v2c -cpublic localhost .1.3.6.1.4.1.2021.8 [9] bekommt man übrigens eine Übersicht über die im SNMP-Dienst eingebundenen ausführbaren Skripte:

UCD-SNMP-MIB::extIndex.1 = INTEGER: 1
UCD-SNMP-MIB::extIndex.2 = INTEGER: 2
UCD-SNMP-MIB::extNames.1 = STRING: mbox_gabriel
UCD-SNMP-MIB::extNames.2 = STRING: mbox_joselia
UCD-SNMP-MIB::extCommand.1 = STRING: /root/bin/mailsize.sh
UCD-SNMP-MIB::extCommand.2 = STRING: /root/bin/mailsize.sh
UCD-SNMP-MIB::extResult.1 = INTEGER: 0
UCD-SNMP-MIB::extResult.2 = INTEGER: 0
UCD-SNMP-MIB::extOutput.1 = STRING: 521066367
UCD-SNMP-MIB::extOutput.2 = STRING: 160176044
UCD-SNMP-MIB::extErrFix.1 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFix.2 = INTEGER: noError(0)
UCD-SNMP-MIB::extErrFixCmd.1 = STRING:
UCD-SNMP-MIB::extErrFixCmd.2 = STRING:

Auf der Easy-Box A800 sind im Übrigen auch Traps aktiviert, so dass der WLAN-Router bei Problemen auf den Schnittstellen eine Mitteilung and den Caipirinha-Server schickt. Darunter fallen beispielsweise auch die Benachrichtigungen über das Zusammenbrechen der Internet-Verbindung wegen der in Deutschland obligatorischen Zwangstrennung nach 24h.

Mit dem Befehl snmpnetstat -v2c -cpublic -Ci -Cn 192.168.3.1 kann man sich die aktiven Netzwerk-Interfaces der A800 anzeigen lassen (public und 192.168.3.1 müssen natürlich entsprechend angepasst werden). Dies sieht dann beispielsweise so aus:

Name              Mtu Network      Address        Ipkts Ierrs    Opkts Oerrs Queue
LOCAL_LOOPBACK   1500 127.0.0.1/32 127.0.0.1          0     0        0     0     1
LAN              1500 192.168.3/24 192.168.3.1 10606794     0  8372114     0     1
WLAN             1500                             50788     0   506993     0     1
ATM1             1500                           8354414     0 11400582     0     1
PPPoE1           1492 88/0         88.74.99.8   8354356     0 11400515     0     1
WDS1             1500                                 0     0   121785     0     1
WDS2             1500                                 0     0   121785     0     1
WDS3             1500                                 0     0   121785     0     1
WDS4             1500                                 0     0   121785     0     1

Man kann klar die Adresse des internen Netzwerks 192.168.3/24 und die momentan zugewiesene externe IP-Adresse 88.74.99.8 erkennen.

Wie im Artikel über SNMP, so gilt auch hier, dass der Community-Name public aus Sicherheitsgründen im gesamten Netzwerk gegen einen anderen, einheitlich benutzten Community-Namen ausgetauscht werden sollte.

Nachdem die Konfigurationsdatei /etc/mrtg.conf angepasst worden ist, muss man mrtg noch explizit starten. Dies geschieht beispielsweise mit: env LANG=C mrtg --user wwwrun --group www --logging /var/log/mrtg.log --lock-file /var/tmp/mrtg --pid-file=/var/run/mrtg.pid /etc/mrtg.conf.

Dem eigentlichen Aufruf von mrtg wird das Kommando env LANG=C voran gestellt, sonst beklagt sich mrtg darüber, dass es nicht in einer Umgebung mit einem UTF8-Zeichensatz laufen kann. Es ist leider bei mrtg nicht möglich, einen automatischen Start über den Runlevel-Editor einzustellen. Man muss das Programm daher nach dem Systemstart manuell starten.

NTP

Aus folgenden Gründen müssen alle Server immer mit der richtigen Uhrzeit laufen:

  • Wenn Daten von einer Maschine zu einer anderen Maschine kopiert werden, müssen die Zeitstempel richtig gesetzt werden., damit nachvollziehbar bleibt, welche Datei wie kopiert worden ist.
  • Log-Dateien müssen exakte Zeitstempel enthalten, um kritische Ereignisse oder unbefugte Zugangsversuche richtig zu protokollieren.
  • Backup-Programme benötigen richtige Zeitstempel, um festzustellen, welche Dateien zu sichern sind und welche Dateien beim Wiederherstellen von Dateien überschrieben werden können.

Der xntp-Dämon ist die erste Wahl auf einer Linux-Maschine, wenn es darum geht, die Uhrzeit zu synchronisieren. Auch der Caipirinha-Server wird über das ntp-Protokoll synchronisiert, allerdings lediglich mit Stratum 2-Maschinen. Eine noch genauere Synchronisation mit Stratum 1-Maschinen ist bei dieser Maschine nicht erforderlich. Auf [1] gibt es ausführliche Informationen über ntp. Es gibt zahlreiche Listen von NTP-Servern im Internet, beispielsweise auf [2].

Um ntp in Betrieb zu nehmen, müssen folgende Pakete installiert werden:

  • xntp
  • xntp-doc
  • yast2-ntp-client.

Dann wird die Konfigurationsdatei /etc/ntp.conf beispielsweise so angepasst:

##
## Undisciplined Local Clock. This is a fake driver intended for backup
## and when no outside source of synchronized time is available.
##
server 127.127.1.0 # local clock (LCL)
fudge  127.127.1.0 stratum 10 # LCL is unsynchronized

driftfile /var/lib/ntp/drift/ntp.drift # path for drift file
logfile   /var/log/ntp
pidfile   /var/run/ntp.pid

##
## Stratum 2 Servers
##
## Universität Augsburg, Deutschland
server tock.fh-augsburg.de             burst
## Observatoire de Paris-Meudon, Frankreich
server ntp.obspm.fr                    burst
## Université de Lyon, Frankreich
server ntp.univ-lyon1.fr               burst
## Instituto Nazionale di Ricerca Metrologica, Torino, IT
server ntp2.ien.it                     burst
## Universität Oslo, Oslo, Norwegen
server fartein.ifi.uio.no              burst
## Bundesamt für Metrologie, Bern, Schweiz
server ntp.metas.ch                    burst
## JANET, Oxfordshire, UK
server ntp2.ja.net                     burst
## Hurricane Electric, San José USA
server clock.sjc.he.net                burst
## Penn State University, USA
server clock.psu.edu                   burst

#
# Authentication stuff
#
keys /etc/ntp.keys              # path for keys file
trustedkey 1                    # define trusted keys
requestkey 1                    # key (7) for accessing server variables
# controlkey 15                 # key (6) for accessing server variables

Seit der Installation von openSuSE 11.2 in der 64-Bit-Version muss ich auf meinem Server übrigens die burst-Anweisung anfügen.

Nachdem die Konfigurationsdatei geändert worden ist, kann der xntp-Dämon mit
/etc/init.d/ntp start aktiviert werden. Nun muss noch dafür Sorge getragen werden, dass xntpd automatisch in den Runleveln (2), 3 und 5 gestartet wird. Dazu markiert man die entsprechenden Felder im Runlevel-Editor in YaST2.

Im abgeglichenen Zustand synchronisiert sich die Uhr des Servers mit den in der Konfigurationsdatei angegebenen NTP-Servern. Ein als root ausgeführtes ntpq -p liefert dann eine Zustandsübersicht über die NTP-Server und zeigt, welcher aktuell als bevorzugter Server gehandelt wird. Die hier wiedergegebene Übersicht stellt eine Momentaufnahme dar.

     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 LOCAL(0)        .LOCL.          10 l   27   64  377    0.000    0.000   0.001
+tock.Informatik 130.149.17.8     2 u   37  512  377  1076.41  -122.51 155.128
*syrte8.obspm.fr 193.52.184.106   2 u   56  512  373  1091.48  -117.02 104.343
-dns.univ-lyon1. 195.220.94.163   2 u  186  512  377  568.388  -376.20 117.041
-ntp2.inrim.it   .CTD.            1 u  141  512  377  876.775  -208.80 304.832
+fartein.ifi.uio 195.220.94.163   2 u  133  512  177  1136.97  -91.214 128.396
-metasweb01.admi .HBGs.           1 u   24  512  377  1149.98  -90.779 155.105
-ntp2.ja.net     .MSF.            1 u   68  512  377  1299.53  -12.322  19.994
-clock.sjc.he.ne .CDMA.           1 u   31  512  377  1766.43  147.929  13.677
-otc2.psu.edu    128.118.2.33     2 u   32  512  377  1390.44  -31.032  48.572

Ab und zu sollte man sich als verantwortlicher Administrator die Datei /var/log/ntp anschauen. Dort sollten dann lediglich Einträge wie diese zu finden sein:

24 Jun 16:47:37 ntpd[3374]: synchronized to 193.204.114.233, stratum 1
24 Jun 16:49:47 ntpd[3374]: synchronized to 193.62.22.98, stratum 1
24 Jun 16:52:58 ntpd[3374]: synchronized to 216.218.254.202, stratum 1
24 Jun 16:53:14 ntpd[3374]: synchronized to 162.23.41.34, stratum 1
24 Jun 16:53:49 ntpd[3374]: synchronized to 193.62.22.98, stratum 1
24 Jun 16:55:09 ntpd[3374]: synchronized to 193.204.114.233, stratum 1
24 Jun 16:55:42 ntpd[3374]: synchronized to 162.23.41.34, stratum 1
24 Jun 16:57:29 ntpd[3374]: synchronized to 193.204.114.233, stratum 1
Posted in IT Tagged

Server-Setup

Hostname und DNS-Server

Der Caipirinha-Server wird in YaST2 mit dem folgenden Hostnamen aufgesetzt:

Hostname:    caipirinha
Domain name: homelinux.org
DNS 1:       195.50.140.252  (Arcor)
DNS 2:       195.50.140.114  (Arcor)
DNS 3:       194.25.2.132    (Deutsche Telekom)

Es ist wichtig, dass die DNS-Server fest eingetragen sind, weil dann die Namensauflösung viel schneller (und problemloser!) funktioniert als wenn der WLAN-Router als DNS-Proxy (192.168.2.1) eingetragen wird.
Da die Maschine an einem Arcor-Anschluß hängt, werden zunächst 2 Arcor DNS-Server und dann noch 1 DNS-Server der Deutschen Telekom eingetragen.

IP-Addresse

Der Caipirinha-Server wird in YaST2 mit der folgenden IP-Adresse konfiguriert:

IP-Addresse:        192.168.2.3
Netz-Maske:         255.255.2.0
Broadcast-Addresse: 192.168.2.255
Default-Gateway:    192.168.2.1

Das Netzwerk 192.168.2.0/24 hat keine Kollisionen mit dem VPN-Netzwerk von HACH-LANGE, so dass es bei Benutzung des Firmen-Notebooks zu Hause keine Probleme gibt und sowohl die Maschinen in der Firma als auch zu Hause sichtbar bleiben.

/etc/hosts

In /etc/hosts müssen nun noch einige fest verdrahtete Rechner im Netzwerk eingetragen werden, und zwar:

192.168.255.10  mojito
192.168.255.3   caipirinha.homelinux.org caipirinha

Partitionierung und Dateisystem

Im Caipirinha-Server befinden sich folgende Festplatten:

  • 3 Platten des Typs WDC WD10EACS-00C7B0, welche in verschiedenen RAID-Arrays für das Betriebssystem und Nutzerdaten verwendet werden
  • 1 Platte des Typs SAMSUNG HD501LJ, welche als Backup-Platte dient

Mit den 3 Platten des Typs WDC WD10EACS-00C7B0 wurden folgende RAID-Arrays definiert (kann man mit cat /proc/mdstat abrufen):

Personalities : [raid6] [raid5] [raid4] [raid0] [raid1]
md3 : active raid5 sda7[0] sdb7[3] sdc7[1]
      1919526144 blocks super 1.0 level 5, 128k chunk, algorithm 0 [3/3] [UUU]
      bitmap: 2/458 pages [8KB], 1024KB chunk

md2 : active raid5 sda6[0] sdb6[3] sdc6[1]
      8401664 blocks super 1.0 level 5, 128k chunk, algorithm 0 [3/3] [UUU]
      bitmap: 1/9 pages [4KB], 256KB chunk

md0 : active raid1 sda1[0] sdb1[2] sdc1[1]
      208800 blocks super 1.0 [3/3] [UUU]
      bitmap: 0/7 pages [0KB], 16KB chunk

md1 : active raid5 sda5[0] sdb5[3] sdc5[1]
      23068928 blocks super 1.0 level 5, 128k chunk, algorithm 0 [3/3] [UUU]
      bitmap: 10/177 pages [40KB], 32KB chunk

Wie man in /etc/fstab erkennen kann, dienen dabei:

  • md0 (RAID-1) als Boot-Partition
  • md1 (RAID-5) als Root-Partition (/)
  • md2 (RAID-5) als Partition für /var
  • md3 (RAID-5) als verschlüsselte Partition für /home

Dann gibt es noch eine verschlüsselte Partition für /backup, welche auf /dev/sdd1 gelegt ist, der einzigen Partition auf der Platte vom Typ SAMSUNG HD501LJ. Die verschlüsselten Partitionen sind in /etc/crypttab gelistet; beim Booten der Maschine muss der Schlüssel an der Konsole eingegeben werden. Demnach muss man beim Booten des Caipirinha-Servers auch persönlich vor Ort sein.

/etc/crypttab:

cr_md3          /dev/md3             none       none
backup          /dev/sdd1            none       none

Die Verschlüsselung soll zwei Zwecke erfüllen:

  • Beim Diebstahl des Servers sollen die Inhalte der Partitionen /home und /backup für den Dieb unbrauchbar sein.
  • Wenn Platten aus dem Server einmal einer weiteren Verwendung zugeführt werden, sollen keine leicht zugänglichen Datenfragmente mehr vorhanden sein.

In /etc/fstab sind noch weitere manuelle Einträge vorhanden:

  • 3 GB SWAP-Speicher wurden gleichmäßig auf die drei Platten /dev/sda, /dev/sdb und /dev/sdc aufgeteilt.
  • /tmp wurde mittels tmpfs ins RAM gemappt

Eigentlich ist es riskant, /tmp ins RAM zu mappen, denn man weiß ja nicht genau, ob irgendwelche Applikationen plötzlich viel Speicherplatz anfordern. Hier wurde dennoch so verfahren, weil auf dem Caipirinha-Server zeitweise ein MIDI-Sequencer läuft, der hohe Anforderungen an die Echtzeitfähigkeit des Systems stellt. Diese Vorgehensweise wurde so empfohlen.

/etc/fstab:

/dev/sda2           swap               swap      defaults 0 0
/dev/sdb2           swap               swap      defaults 0 0
/dev/sdc2           swap               swap      defaults 0 0
/dev/md0            /boot              ext3      acl,user_xattr 1 2
/dev/md1            /                  reiserfs  acl,user_xattr 1 1
/dev/md2            /var               reiserfs  acl,user_xattr 1 2
none                /tmp               tmpfs     defaults 0 0
/dev/mapper/cr_md3  /home              reiserfs  acl,user_xattr,noauto 0 0
/dev/mapper/backup  /backup            ext3      acl,user_xattr,noauto 0 0
proc                /proc              proc      defaults 0 0
sysfs               /sys               sysfs     noauto 0 0
debugfs             /sys/kernel/debug  debugfs   noauto 0 0
usbfs               /proc/bus/usb      usbfs     noauto 0 0
devpts              /dev/pts           devpts    mode=0620,gid=5 0 0

Die restlichen Einträge werden beim Setup des Systems automatisch erzeugt.

/etc/security/limits.conf

Die hier manuell eingefügten Änderungen (@audio) betreffen in erster Linie die Anforderungen an die Echtzeitfähigkeit des Caipirinha-Servers für den Einsatz von MIDI-Sequencern. Daneben habe ich mir als User noch die Möglichkeit reserviert, meine eigenen Prozesse etwas höher als der Durchschnitt priorisieren zu können.

#<domain>      <type>  <item>         <value>
...
@audio          -       rtprio          99
@audio          -       memlock         unlimited
gabriel         hard    nice            -5

# End of file

Nützliche Befehle

Auf dieser Seite gibt es eine Liste verschiedener Unix-Befehle samt Optionen, die ich immer mal wieder benötige.

Doppelte Dateien finden

So sucht man doppelte Dateien in einem Verzeichnis (hier im Beispiel: /home/tmp):

find /home/tmp -not -type l -exec md5sum {} 2>/dev/null \; | sort | uniq -w32 -D --all-repeated=separate | cut -c35-

Werden doppelte Dateien gefunden, erhält man solche Treffer:

/home/tmp/Gesichter.ppt
/home/tmp/Rostos.ppt

/home/tmp/Gedanken_des_Tages.pps
/home/tmp/PensamentosdoDia.pps

Offene Ports

Offene Ports und die zugehörigen Programme kann man mit diesem Befehl finden:

lsof -i4 -n -P

Damit beschränkt man sich allerdings auf das IP-Protokoll in der Version 4. Außerdem werden Rechnernamen und Portnummern nicht aufgelöst, sondern nur numerisch dargestellt. Man erhält dann beispielsweise diese Ausgabe:

COMMAND     PID      USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
portmap    3040       bin    4u  IPv4    8673      0t0  UDP *:111
portmap    3040       bin    5u  IPv4    8679      0t0  TCP *:111 (LISTEN)
nmbd       3182      root    7u  IPv4    9161      0t0  UDP *:137
nmbd       3182      root    8u  IPv4    9162      0t0  UDP *:138
nmbd       3182      root    9u  IPv4    9164      0t0  UDP 192.168.2.2:137
nmbd       3182      root   10u  IPv4    9165      0t0  UDP 192.168.2.2:138
apcupsd    3186      root    5u  IPv4    9956      0t0  TCP *:3551 (LISTEN)
avahi-dae  3332     avahi   13u  IPv4    9825      0t0  UDP *:5353
avahi-dae  3332     avahi   14u  IPv4    9826      0t0  UDP *:47151
cupsd      3448      root    2u  IPv4   10227      0t0  TCP *:631 (LISTEN)
clamd      3492     vscan    4u  IPv4   10117      0t0  TCP 127.0.0.1:3310 (LISTEN)
mysqld-ma  3561     mysql   11u  IPv4   10232      0t0  TCP *:3306 (LISTEN)
amavisd    3606     vscan    7u  IPv4   10316      0t0  TCP 127.0.0.1:10024 (LISTEN)
pptpd      3723      root    6u  IPv4   10707      0t0  TCP *:1723 (LISTEN)
pure-ftpd  3738      root    4u  IPv4   10739      0t0  TCP *:21 (LISTEN)
amavisd    3791     vscan    7u  IPv4   10316      0t0  TCP 127.0.0.1:10024 (LISTEN)
amavisd    3792     vscan    7u  IPv4   10316      0t0  TCP 127.0.0.1:10024 (LISTEN)
sshd       3794      root    4u  IPv4   11048      0t0  TCP *:22 (LISTEN)
famd       3852 mailowner    3u  IPv4   11257      0t0  TCP 127.0.0.1:636 (LISTEN)
master     3906      root   11u  IPv4   11499      0t0  TCP *:25 (LISTEN)
master     3906      root  106u  IPv4   11642      0t0  TCP 127.0.0.1:10025 (LISTEN)
vlc        3979    wwwrun    5u  IPv4 2075026      0t0  TCP *:4212 (LISTEN)
snmptrapd  4168      root    9u  IPv4   13963      0t0  UDP *:162
sshd       6397      root    3u  IPv4 3527486      0t0  TCP 192.168.2.2:22->213.61.59.222:3940 (ESTABLISHED)
sshd       6550      root    3u  IPv4 3528133      0t0  TCP 192.168.2.2:22->213.61.59.222:27817 (ESTABLISHED)
sshd       6550      root    6u  IPv4 3528205      0t0  TCP 127.0.0.1:6010 (LISTEN)
sshd       6738      root    3u  IPv4 3529868      0t0  TCP 192.168.2.2:22->213.61.59.222:45180 (ESTABLISHED)
sshd       6738      root    6u  IPv4 3529942      0t0  TCP 127.0.0.1:6011 (LISTEN)
sshd       7465      root    3r  IPv4 3556103      0t0  TCP 192.168.2.2:22->213.61.59.222:37268 (ESTABLISHED)
sshd       7465      root    6u  IPv4 3556173      0t0  TCP 127.0.0.1:6013 (LISTEN)
mrtg      11646    wwwrun    4u  IPv4 3560096      0t0  UDP *:33150
snmpd     14786      root    7u  IPv4 3498190      0t0  TCP 127.0.0.1:199 (LISTEN)
snmpd     14786      root    8u  IPv4 3498188      0t0  UDP *:45681
snmpd     14786      root    9u  IPv4 3498191      0t0  UDP *:161
sshd      24534      root    3r  IPv4 3550583      0t0  TCP 192.168.2.2:22->213.61.59.222:12882 (ESTABLISHED)
sshd      24534      root    6u  IPv4 3550658      0t0  TCP 127.0.0.1:6012 (LISTEN)
ntpd      32080       ntp   16u  IPv4 2379133      0t0  UDP *:123
ntpd      32080       ntp   20u  IPv4 2379140      0t0  UDP 127.0.0.1:123
ntpd      32080       ntp   21u  IPv4 2379141      0t0  UDP 127.0.0.2:123
ntpd      32080       ntp   22u  IPv4 2379142      0t0  UDP 192.168.2.2:123

Mit lsof -i4tcp -n -P kann man die Ausgabe auf reine TCP-Verbindungen beschränken, mit lsof -i4udp -n -P beschränkt man die Ausgabe entsprechend auf reine UDP-Verbindungen.

Posted in IT