התקנת והגדרת שרת גיבוי Bacula על גבי דביאן

היסטוריית גירסאות
גירסה 1.1 23-06-2008 <eitant>
גירסה שנייה

תקציר

זהו מדריך להתקנת תוכנת בקולה על גבי שרת דביאן עם תמיכה בשמות קבצים בעברית.

שם מסמך זה באנגלית: Install Bacula with Hebrew support on a Debian server

זכויות יוצרים ורשיון

כל הזכויות שמורות © 2008, <eitant>, הרשות ניתנת להעתיק, לשנות ולהפיץ מדריך זה תחת התנאים של רשיון ה-GFDL
Linux הוא סימן מסחרי רשום של Linus Torvalds.

הסרת אחריות

הכותב אינו נושא באחריות עבור שימוש ברעיונות, דוגמאות ומידע שבמדריך. השימוש הוא באחריות הקורא בלבד. המדריך עשוי להחיל טעויות ופרטים לא נכונים, שהשימוש בהם עשוי להיות מזיק למחשבך. למרות הסבירות נמוכה, הכותב אינו לוקח כל אחריות

מבוא

הבקולה הינה תוכנה לגיבוי מחשבים ברשת.
הגיבוי יכול להתבצע לספריה מסוימת בשרת על גבי טייפ גיבוי או בצריבה על גבי מדיה.
במדריך הזה אני אסביר איך לגבות לספרייה בשרת.
היא משתמשת ב-VSS של Windows XP, 2003, Vista לצורך גיבוי קבצים פתוחים בתחנות Windows לדוגמא קבצי Personal Folders.
המבנה הבסיסי הוא של שרת ראשי ותחנות שמאזינות לבקשות מהשרת.
הגיבוי ניתן לביצוע בצורה מתוזמנת מראש או ידנית.

הבקולה משתמשת בשלושה שירותים

Bacula-Director

השרות הנ”ל הוא למעשה לב המערכת של השרת, השרת שמריץ את השרות הזה משמש כשרת הגיבוי.

Bacula-SD

השרות הנ”ל משמש לניהול איחסון הגיבויים.

Bacula-FD

השרות הנ”ל משמש לגיבוי התחנות, הוא צריך לרוץ על כל תחנה או שרת שצריכים לעבור גיבוי.

התקנת השרת

הכנת השרת להתקנה

יש לוודא שבקובץ ה-HOSTS רשומה הכתובת האמיתית של השרת ראשונה ולא 127.0.0.1

# vim /etc/hosts

לדוגמא:

192.168.0.100	BACULA
127.0.0.1	localhost
# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts

הורדה והתקנה של כל התוכנות הנדרשות

# apt-get install mysql-server gcc libmysqlclient15-dev g++ 
# apt-get install make libncurses5-dev
הורדה והתקנה של הבקולה

ניתן להוריד את התוכנה מאחד השרתים הבאים: Sourceforge - Bacula Download

לדוגמא:

# wget http://heanet.dl.sourceforge.net/sourceforge/bacula/bacula-2.4.0.tar.gz
  
חילוץ הקבצים
# tar –xvvf bacula-2.4.0.tar.gz
התקנת השרת
# cd bacula-2.4.0
# ./configure -with-mysql
# make
# make install
הוספת תמיכה בעברית
# vim src/cats/create_mysql_database
יש לשנות את השורה
;{CREATE DATABASE ${db_name
ל-
;CREATE DATABASE ${db_name} CHARACTER SET=hebrew

לפני השינוי
if $bindir/mysql $* -f <<END-OF-DATA
CREATE DATABASE ${db_name};
END-OF-DATA


אחרי השינוי

if $bindir/mysql $* -f <<END-OF-DATA
CREATE DATABASE ${db_name} CHARACTER SET=hebrew;
END-OF-DATA
יצירת הטבלאות ב-My-Sql
# cd src/cats
# ./create_mysql_database
# ./make_mysql_tables
# ./grant_mysql_privileges
יצירת השירותים
# cp /etc/bacula/bacula-ctl-fd /etc/init.d/bacula-fd
# cp /etc/bacula/bacula-ctl-dir /etc/init.d/bacula-director
# cp /etc/bacula/bacula-ctl-sd /etc/init.d/bacula-sd
# chmod 755 /etc/init.d/bacula-sd
# chmod 755 /etc/init.d/bacula-fd
# chmod 755 /etc/init.d/bacula-director
# update-rc.d bacula-sd defaults 90
# update-rc.d bacula-fd defaults 91
# update-rc.d bacula-director defaults 92
הפעלת השירותים
# /etc/init.d/bacula-sd start
# /etc/init.d/bacula-fd start
# /etc/init.d/bacula-director start

הגדרות כלליות בשרת

השרת מותקן בספריית bacula מתחת לספריית etc
הקובץ המרכזי של השרת נקרא bacula-dir.conf
הקובץ שמרכז את נתוני שרת הגיבוי נקרא bacula-sd.conf

שינוי והוספת הגדרות גיבוי

הגדרות אילו אינן חובה אך מומלצות והן משתנות מארגון לארגון לפי צרכיו ומשאביו.
אם מבצעים שינויים בקבצים יש להפעיל מחדש את שלושת השירותים על מנת שהשינויים יכנסו לתוקף.

# /etc/init.d/Bacula-director restart
# /etc/init.d/bacula-sd restart
# /etc/init.d/bacula-fd restart

לשינוי הגדרות צורת הגיבוי, זמני הגיבוי וסוגי הקבצים שיש לגבות נערוך את הקובץ הראשי ונשנה או נוסיף שורות רלוונטיות

# vim /etc/bacula/bacula-dir.conf

שינוי מספר המחשבים שמגובים בו זמנית
ניתן להחליף את המספר למספר יותר גבוה על מנת שמספר גיבויים ירוצו יחדיו (המספר תלוי בעוצמת המחשב).

 Maximum Concurrent Jobs = 1

הוספת תזמונים נוספים
ניתן להוסיף זמנים נוספים של גיבויים לפי הצורך

Schedule {
Name = PC
Run = Level=Full tue at 22:55
Run = Level=Full sat at 22:55
}

Schedule {
Name = SERVER 
Run = Level=Full Full sat at 22:55
}

Schedule {
Name = Laptop
Run = Level=Full sun at 13:00
Run = Level=Full wed at 13:00
}

סוגי קבצים לגיבוי ומיקומם
סוגי הקבצים ומיקומם נמצאים ב-fileset אני ממליץ ליצור אחד נוסף עם ההגדרות הנוחות לאותו ארגון.
ניתן ליצור מספר fileset בעלי שמות שונים על מנת לתמוך באפשרויות שונות של גיבוי.

לדוגמא:
fileset לתחנת windows XP בעלת כוננים C ו-D שיגבה את הקבצים הבאים: ,vsd, pdf, pst, xls, doc, ppt, pps

סוגי הקבצים לגיבוי

Fileset 
{
Name = Drives_CD
         Include{
              Options{
                      WildFile=*.pst 
                      Wildfile=*.xls
                      WildFile=*.doc
                      WildFile=*.ppt
                      WildFile=*.pps
                      WildFile=*.vsd
                      WildFile=*.pdf
                      signature = MD5
                     }

קבצים וספריות שאין צורך לגבות אותם

Options{
   wildfile=*.*
   exclude=yes
   IgnoreCase = yes
   compression = gzip
   WildDir = "[A-Z]:/Documents and Settings/*/Cookies"
   WildDir = "[A-Z]:/Documents and Settings/*/Recent"
   WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/History"
   WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/Temp"
   WildDir = "[A-Z]:/Documents and Settings/*/Local Settings/Temporary Internet Files"
   WildDir = "[A-Z}:/MSOCache"
   WildDir = "[A-Z]:/WINDOWS/$Nt*Uninstall*"
   WildDir = "[A-Z]:/RECYCLER"
   WildDir = "[A-Z]:/System Volume Information"
   WildFile = "[A-Z]:/pagefile.sys"
       }

באילו כוננים לחפש את הקבצים בעלי הסיומות הללו

     File = c:/
     File = d:/
}
הגדרת מקום הגיבוי

כדי להגדיר לאיזו ספרייה יתבצע הגיבוי, יש לערוך את הקובץ bacula-sd.conf

# vim /etc/bacula/bacula-sd.conf

בשורה = Archive Device נרשום את שם הספריה אליה יתבצעו הגיבויים.

Device {
Name = FileStorage
Media Type = File
Archive Device = 
LabelMedia = yes;                   # lets Bacula label unlabeled media
Random Access = Yes;
AutomaticMount = yes;               # when device opened, read it
RemovableMedia = no;
AlwaysOpen = no;
}

הוספת מחשבים לגיבוי

בפרק זה נראה כיצד להוסיף תחנת Windows לגיבוי, על ידי התקנת הסוכן בתחנה והוספתו לרשימת הגיבויים בשרת.

התקנת הסוכן בתחנה

ההתקנה היא התקנה מאוד פשוטה.
לאחר ההתקנה קבצי ההגדרות נשמרים ב-C:\Documents And Settings\All Users\Aplication Data\Bacula
קובץ הההגדרות המרכזי נקרא Bacula-fd.conf הוא מכיל את שם השרת שמותר לו לפנות לאותה תחנה.
אם מבצעים שינוי בקובץ יש לעצור ולהפעיל מחדש את השירות של ה-Bacula

הורדת הסוכן לתחנה

ניתן להוריד את התוכנה מכאן Bacula-Win32 download

בסוג החבילה יש לבחור ב-Win32.

התקנת הסוכן

בדוגמא שלפנינו השרת נקרא BACULA
מריצים את הקובץ
וממשיכים עם ברירות המחדל


בשורה העליונה יש לרשום את dir-שם השרת,
יש לרשום את שם השרת במדויק (יש חשיבות לאותיות גדולות וקטנות).
בשורה השנייה יש לרשום סיסמא כלשהיא.
ובשורה השלישית את שם השרת.

ניתן לבטל את הסימן


בפינה הימנית התחתונה תופיע תמונה של קלטת, לקלטת יכולים להיות מספר צבעים
ירוק - המחשב כרגע מגובה.
צהוב - הגיבוי הסתיים עם אזהרות.
אדום - הגיבוי נכשל.
לבן - מצב המתנה.

הוספת תחנה לרשימת הגיבויים בשרת

על מנת שהשרת יכיר את התחנה צריך להוסיף אותה לקבצי ההגדרות של השרת.
קיים סקריפט שעושה את ההוספה אוטומטית מי שמעוניין מוזמן לפנות אלי למייל eitant@gmail.com
יש להוסיף כל תחנה בשתי מקומות:
1. בקובץ הראשי: bacula-dir.conf
2. בקובץ שמגדיר להיכן לגבות את התחנה: bacula-sd.conf

נתחיל בקובץ הראשי

# vim /etc/bacula/bacula-dir.conf

יש להוסיף את ארבעת הפיסקאות הבאות:

פיסקה ראשונה Client
Name = שם מזהה לפיסקה
Password = להשאיר את זה אלא אם כן בוצע שינוי ידני לסיסמא בתחנה
Address = שם התחנה לגיבוי
FDPort = באיזה פורט התחנה מאזינה
Catalog = היכן לשמור את האינדקס, אין צורך לשנות

Client {
Name = eitant-fd
Password = "@client_password@"
Address = eitant
FDPort = 9102
Catalog = MyCatalog
        }

פיסקה שנייה Job
Name = שם מזהה לפיסקה
Type = תפקיד גיבוי או שיחזור
Level = סוג הגיבוי
Client = פונה לפיסקה הקודמת (מזוהה לפי השם)
FileSet = פונה ל-fileset המתאים על מנת לבדוק מה לגבות
Schedule = פונה ל-Schedule המתאים על מנת לבדוק מתי לגבות
Storage = פונה ל-Storage המתאים לקבלת נתונים לגבי שרת האיחסון
Pool = פונה ל-Pool המתאים על מנת לתת שם לאותו גיבוי
Messages = באיזו צורה להוציא הודעות
ClientRunAfterJob = אפשרות להריץ פקודה על התחנה בסוף הגיבוי (אפשר גם לפני בעזרת ClientRunBeforeJob)

Job {
Name = Eitan
Type = Backup
Level = Full
Client = eitant-fd
FileSet = Drives_CD
Schedule = PC 
Storage = Eitant
Pool = Eitant
Messages = Standard
ClientRunAfterJob = "c:/WINDOWS/system32/defrag.exe c: -f"
 }

פיסקה שלישית Storage
Name = שם מזהה לפיסקה
Address = שם השרת שעליו ישמרו הגיבויים
SDPort = הפורט ששרת הגיבויים מאזין
Password = סיסמא לתקשורת עם שרת הגיבויים, משתנה משרת לשרת, הסיסמא של של השרת נמצאת בפיסקת ה-Storage שנוצרה בקובץ bacula-dir.conf
Device = מציין לאיזו פיסקה לפנות בקובץ של המדיה bacula-sd.conf
Media Type = מציין את סוג המדיה לגיבוי

Storage {
Name = Eitant 
Address = BACULA                # N.B. Use a fully qualified name here
SDPort = 9103
Password = "uKs0SnYBNx2OqRkP8Ap1IlZsr19jshMka6YWJv5k"
Device = Eitant 
Media Type = File
}  

פיסקה רביעית Pool
Name = שם מזהה לפיסקה
Use Volume Once = האם להשתמש באותו קובץ למספר גיבויים או כל קובץ לגיבוי אחד
Pool Type = מה תפקיד הקובץ
LabelFormat = מבנה שם קובץ הגיבוי
AutoPrune = האם לבצע מחיקה אוטומטית של גיבוים ישנים שפג תוקפם
Maximum Volumes = מספר הקבצים המקסימלי למשתמש
Recycle = האם למחזר קבצים
Volume Retention = כמה זמן לשמור כל קובץ לפני שתתאפשר מחיקתו

Pool {
Name = Eitant
Use Volume Once = yes
Pool Type = Backup
LabelFormat = "Eitant-"
AutoPrune = yes
Maximum Volumes = 2 
Recycle = yes
Volume Retention = 4 days
}

כעת נגדיר את הקובץ השני

# vim /etc/bacula/bacula-sd.conf

Name = שם מזהה לפיסקה
Media Type = סוג המדיה
Archive Device = לאיזה ספרייה לגבות
LabelMedia = האם לתת שם לקובץ
Random Access = גישה אקראית לנקודת הכתיבה (ישים בקלטות גיבוי)
AutomaticMount = טעינה אוטומטית של המדיה (ישים ברובוטי גיבוי)
RemovableMedia = האם זאת מדיה שליפה
AlwaysOpen = האם לסגור את המדיה (ישים לצורבים)

Device {
Name =רyes
Random Access = yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
}

לאחר הוספת תחנה/ות יש להפעיל את השירותים מחדש

מומלץ לבדוק שיש תקשורת בין התחנה לשרת

# bconsole

מתקבל המסך הבא

Connecting to Director BACULA:9101
1000 OK: BACULA-dir Version: 2.2.8 (26 January 2008)
Enter a period to cancel a command.
*

מקישים status ומקבלים

Status available for:
   1: Director
   2: Storage
   3: Client
   4: All
Select daemon type for status (1-4):

מקישים 3

The defined Client resources are:
   1: BACULA-fd
   2: eitant-fd
Select Client (File daemon) resource (1-2):

בוחרים את התחנה הרצויה, ואם השרת מצליח ליצור קשר עם התחנה יתקבל מסך דומה למסך זה

Connecting to Client eitant-fd at eitant:9102

eitant-fd Version: 2.2.7 (24 December 2007)  VSS Linux Cross-compile Win32
Daemon started 29-Apr-08 15:56, 3 Jobs run since started.
 Heap: heap=0 smbytes=10,145 max_bytes=300,266 bufs=61 max_bufs=251
 Sizeof: boffset_t=8 size_t=4 debug=0 trace=1

Running Jobs:
Director connected at: 08-May-08 10:59
No Jobs running.
====

ניהול השרת

קיימות שתי אפשרויות לנהל את השרת:
1. פקודות טקסט
2. צורה גרפית דרך Webmin

האפשרות הראשונה יותר מהירה ובזמן הרצת גיבוי באופן יזום או ביצוע הגדרות לשרת כמו הוספת תחנות וגם לבניית היא Fileset יותר נוחה.
היתרונות של העבודה הגרפית היא האפשרות לשחזר ביתר נוחות קבצים.

גיבוי יזום

כדי לגבות תחנה ישנן שתי אפשרויות:

דרך הקונסול

# bconsole

מתקבל המסך הבא

Connecting to Director BACULA:9101
1000 OK: BACULA-dir Version: 2.2.8 (26 January 2008)
Enter a period to cancel a command.
*

מקישים run

ומקבלים

Automatically selected Catalog: MyCatalog
Using Catalog "MyCatalog"
A job name must be specified.
The defined Job resources are:
     1: Client1
     2: BackupCatalog
     3: RestoreFiles
     4: eitant
Select Job resource (1-4):

בוחרים את התחנה לגיבוי, מופיע המסך הבא

Run Backup job
JobName:  eitant
Level:    Full
Client:   eitant-fd
FileSet:  Drives_CD
Pool:     eitant (From Job resource)
Storage:  eitant (From Job resource)
When:     2008-05-07 08:30:46
Priority: 10
OK to run? (yes/mod/no):

מקישים yes להתחלת הגיבוי

כדי לראות את ההודעות של הגיבוי ניתן להקיש messages

דרך Webmin
לוחצים על Run Backup Job

בוחרים את התחנה הרצויה ולוחצים על Backup Now

במסך שיופיע רואים את התקדמות הגיבוי

שחזור נתונים

כדי לשחזר תחנה ישנן שתי אפשרויות:

דרך הקונסול

# bconsole

מתקבל המסך הבא

Connecting to Director BACULA:9101
1000 OK: BACULA-dir Version: 2.2.8 (26 January 2008)
Enter a period to cancel a command.
*

נרשום restore

Automatically selected Catalog: MyCatalog
Using Catalog "MyCatalog"

First you select one or more JobIds that contain files
to be restored. You will be presented several methods
of specifying the JobIds. Then you will be allowed to
select which files from those JobIds are to be restored.

To select the JobIds, you have the following choices:
   1: List last 20 Jobs run
   2: List Jobs where a given File is saved
   3: Enter list of comma separated JobIds to select
   4: Enter SQL list command
   5: Select the most recent backup for a client
   6: Select backup for a client before a specified time
   7: Enter a list of files to restore
   8: Enter a list of files to restore before a specified time
   9: Find the JobIds of the most recent backup for a client
  10: Find the JobIds for a backup for a client before a specified time
  11: Enter a list of directories to restore for found JobIds
  12: Cancel
Select item:  (1-12):

לצורך הדוגמא נבחר באופציה 5

Defined Clients:
   1: eitant-fd
   2: BACULA-fd
Select the Client (1-2):

נבחר בתחנה לגיבוי

Automatically selected FileSet: Drives_CD
+-------+-------+----------+---------------+---------------------+-------------+
| JobId | Level | JobFiles | JobBytes      | StartTime           | VolumeName  |
+-------+-------+----------+---------------+---------------------+-------------+
|   107 | F     |   10,416 | 4,546,504,538 | 2008-05-06 22:55:01 | Eitant-0003 |
+-------+-------+----------+---------------+---------------------+-------------+
You have selected the following JobId: 107

Building directory tree for JobId 107 ...  ++++++++++++++++++++++++++++++++++
1 Job, 7,181 files inserted into the tree.

You are now entering file selection mode where you add (mark) and
remove (unmark) files to be restored. No files are initially added, unless
you used the "all" keyword on the command line.
Enter "done" to leave this mode.

cwd is: /
$

כדי לראות את רשימת הקבצים נשתמש בפקודה ls
כדי לעבור בין ספריות נשתמש בפקודה cd
כדי לבחור קבצים לגיבוי נרשום mark ולאחריו את שם הקובץ
אם רוצים לשחזר הכול רושמים all
כאשר מסיימים לבחור רושמים done

Bootstrap records written to /var/bacula/working/BACULA-dir.restore.2.bsr

The job will require the following
   Volume(s)                 Storage(s)                SD Device(s)
===========================================================================

   Eitant-0003               Eitant                    Eitant


1 file selected to be restored.

Run Restore job
JobName:         RestoreFiles
Bootstrap:       /var/bacula/working/BACULA-dir.restore.2.bsr
Where:           /tmp/bacula-restores
Replace:         always
FileSet:         Full Set
Backup Client:   Eitan_Talmi-fd
Restore Client:  Eitan_Talmi-fd
Storage:         Eitant
When:            2008-05-09 18:44:55
Catalog:         MyCatalog
Priority:        10
OK to run? (yes/mod/no):

אם רוצים להריץ ללא שינויים כותבים yes ואם רוצים לשנות משהו כותבים mod
כברירת מחדל השחזור מתבצע ל-tmp\bacula-restores\

דרך Webmin

לוחצים על Restore Backup

Job to restore - בוחרים את הגיבוי שממנו רוצים לשחזר
Files to restore - בוחרים את הקבצים לשחזור (חייבים JAVA על מנת לראות את הקבצים והספריות).
שמות הקבצים בעברית יופיעו בצורה משובשת-לאחר השחזור השמות מופיעים בצורה תקינה.
אם רוצים לשחזר שם קובץ בעברית בעל יותר ממילה אחת בשם הקובץ, יש לשחזר את כל הספרייה שלו.
Restore from storage device - בוחרים את ה-Storage שבו נמצא הגיבוי.
Restore to client or group - לאן לשחזר, למחשב המקורי או למחשב אחר.
Restore to directory - לאיזו ספרייה לשחזר.
לוחצים על Restore now ולאחר מספר שניות יופיע קצב ההתקדמות של השחזור.

אפשרויות מתקדמות

Bootstrap - קבצים אילו משמשים כאפשרות לשחזר את הגיבויים גם במקרה של קריסת ה-DataBase.
ניתן ליצור את הקבצים לכל משתמש בצורה אוטומטית על ידי הוספת שורה בקובץ bacula-dir.conf

Job {
Name = Eitan_Talmi
Type = Backup
Level = Full
Client = Eitan_Talmi-fd
FileSet = Drives_CD
Schedule = PC
Storage = Eitant
Pool = Eitant
Messages = Standard
ClientRunAfterJob = "c:/WINDOWS/system32/defrag.exe c: -f"
Write Bootstrap = "/Backup/Bootstrap/Eitan_Talmi.bsr"
}

במקרה שיש צורך לבצע שיחזור וחייבים להשתמש ב-Bootstrap.

eitant.bsr - שם קובץ ה-Bootstrap שברשותינו.
backup - שם הספרייה שהא נמצא קובץ הגיבוי.
tmp - לאן לשחזר.

#  bextract -b eitant.bsr /Backup /tmp

שליחת הודעות בדואר אלקטרוני
בבקולה קיימת מערכת למשלוח דואר לגבי דוחות גיבויים.
כדי לשנות את ההגדרות יש לערוך את הקובץ bacula-dir.conf
-h = יש לרשום את שם שרת הדואר
mail = יש לרשום את כתובת הדואר של מי שאנו רוצים לשלוח לו דואר לגבי גיבוי
ניתן להוסיף גם שורה mail on error בנוסף או במקום mail עם כתובת הדואר של מי שישלחו אליו הודעות לגבי גיבויים שנכשלו.
operatorcommand = יש לרשום את כתובת הדואר של מי שאנו רוצים לשלוח לו דואר לגבי גיבוי שממתין להתערבות חיצונית.

mailcommand = "/sbin/bsmtp -h mail.example.com -f \"\(Bacula\) \<%r\>\" -s \"Bacula: %t %e of %c %l\" %r"
operatorcommand = "/sbin/bsmtp -h mail.example.com -f \"\(Bacula\) \<%r\>\" -s \"Bacula: Intervention needed for %j\" %r"
mail = eitant@exmaple.com = all, !skipped
operator = eitan@exmaple.com = mount
console = all, !skipped, !saved

משוב

תגובות, תלונות, הערות והארות לכתובת: eitant@gmail.com.

מידע נוסף

למידע נוסף ופירוט מעמיק של שרת הבקולה נמצא באתר הרשמי של בקולה

מדריכים/התקנת_והגדרת_שרת_גיבוי_bacula.txt · שונה לאחרונה ב: 2008/07/03 11:05 על ידי eitantalmi
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0