Тъй, да видим утре коя друга оптика, освен тази на MSAT Cable ще се окаже пострадала.
Днес около 19.30 е прекъснат магистрален оптичен кабел в района на Аспарухов мост. За момента не знам подробности, но нещо ме навежда на мисълта, че подозренията ще се наклонят здраво към „уважаемите колеги“ от И****билд. Дано да е инцидент и те да нямат нищо общо.
Защото ако имат, това може да се окаже грешка, и то сериозна.
Допълнение: Да, наистина имаше прерязана оптика на MSAT Cable. Интересното е, че заедно вървят две HDPE тръби – едната е на MSAT, а другата – на SPNet. Тръбата на Спектър е здрава, но не и тази на MSAT. Дали ще съм прав, ако предположа, че целта вероятно е била оптиката на SPNet, но погрешка е била презярана другата тръба?
Бффф… все си мислех, че тази работа ще спре някога, но по всичко изглежда, че няма да е скоро. И все пак, не искам да обвинявам конкретно някого – няма свидетели, и е напълно възможно да е бил всеки.
Който и да го е направил, то си знае…
Втора редакция : Всъщност излезе, че това е най-обикновен FUD. Извинявам се за което – причината за прекъсването на оптичния кабел е подпален (по неизвестна причина) стълб.
Извадка от документацията към дистрибуцията ALTQ – първата свободна
имплементация на HFSC, разработена в Университета Карнеги Мелън за xBSD.
По-късно е пренесена от Патрик МакХарди в Linux 2.4/2.6.
Следният документ представлява добър справочен материал, но е твърде теоретичен.
Ето защо тук ще изложим основите на HFSC.
„A Hierarchical Fair Service Curve Algorithm for Link-Sharing, Real-Time and
Priority Service“ Ion Stoica, Hui Zhang, and T. S. Eugene Ng. SIGCOMM’97.
Документът може да бъде намерен тук:
http://www.minus273.org/wp-content/uploads/2008/01/sigcom97.pdf
Още информация има тук:
http://www.cs.cmu.edu/~hzhang/HFSC/main.html
-
Сервизна крива:
HFSC поддържа 2 сервизни криви – една за реално-времеви критерии, а другата за
критерии на разпределение на линията.
Сервизната крива на HFSC се състои от 2 сегмента. „m1″ и „m2″ са кривините на
двата сегмента, а „d“ е x-проекцията на точката на пресичане, която определя
дължината на първия сегмент. Логично, „m2″ указва производителността,
гарантирана на един поток в дългосрочен план, докато „m1″ указва скоростта, с
която се обслужва един изблик (burst). Когато кривината на първия сегмент е
по-голяма от тази на втория, я наричаме „вдлъбната“. Една сервизна крива може да
бъде или вдлъбната, или изпъкнала.
m2 ________
________-------- /
/ m2 /
/ /
m1 / /
/ m1 = 0 /
/ __________/
<-d-> <-- d --->
concave convex
Една вдлъбната сервизна крива осигурява ограничен изблик (burst), подобно на
token-bucket. Триъгълната област, образувана от първия сегмент приблизително
съответства на дълбочината на token-bucket, а кривината ограничава нейната
пикова стойност.
Разликата се състои в това, че пиковата стойност на token-bucket е горна граница
на скоростта на изпращане и често се установява на скоростта, която позволява
физическата линия. От друга страна, HFSC гарантира скоростта, дефинирана от
първия сегмент, и следователно не може да бъде установена на скоростта на
физическата линия.
Изпъкналата сервизна крива, от друга страна, потиска първоначалния обем трафик.
„m1″ на изпъкналата крива трябва да бъде 0 в настоящата имплементация.
Една линейна сервизна крива е специален случай на изпъкнала крива с първи
сегмент NULL (т.е. празна стойност).
Линейната сервизна крива съответства на традиционния модел на виртуалния
часовник и е добра отправна точка за потребители-новобранци.
-
Виртуално време:
Всеки клас пази общия брой байтове, които вече е изпратил. Когато даден клас се
препълни, за пакета на върха на опашката се калкулира виртуално време vt. То
представлява x-проекция на сервизната крива, съответстваща на (total + packet_len).
В резултат на това vt на даден клас се увеличава монотонно.
Като се даде път на пакета с най-малко виртуално време, разпределението на
капацитет става пропорционално на кривината на сервизната крива на всеки клас.
bytes
| /
| /service curve
| /
next -->+ +----------------+
packet | | /|
length | | / |
| | / |
total --> + +------------+ |
bytes | /| |
already | / | |
sent | / | |
/ | |
| |
| |
--------+---+--------------> time
vt for next packet
vt for previous packet
Сервизната крива се обновява всеки път, когато даден клас се препълни.
Операцията по обновяването взема като минимум
(1) Сервизната крива, използвана при предишния период на препълване
и
(2) оригиналната сервизна крива, която започва в (current_time, total_bytes).
Когато един клас бъде неактивен достатъчно дълго, обновената крива е равна на
(2). От друга страна, когато класът е използвал много повече капацитет от
заделеното за него, обновената сервизна крива е равна на (1). (1) и (2) могат да
се пресекат, когато класът е използвал капацитет съвсем малко по-малък от
своя дял. В този случай, обновената крива би имала различна стойност „d“.
Операцията е илюстрирана в следните фигури. Може би е по-лесно да се разглежда
като полу-празна token-bucket.
________
________--------
/ ______
/ ________--------
________---+----
/ /
/ /
total -> / + new coordinate
/
/
service curve |
of +
previous period current
time
Update Operation
______
________--------
+----
/
/
total -> + new coordinate
|
+
current
time
New Service Curve
-
HFSC планиране:
HFSC има два независими механизма за планиране. Планирането в реално време се
използва, за да се гарантира едновременно закъснението и разпределението на
мрежов капацитет.
Йерархичното планиране се използва, за да се разпредели излишния капацитет, ако
има наличен такъв.
Когато един пакет излиза от опашката, HFSC винаги опитва първо планиране в
реално време. Ако никой пакет не подлежи на планиране в реално време, се
изпълнява йерархично планиране. HFSC не използва йерархията на класовете за
планиране в реално време.
-
Йерархично планиране:
В HFSC само крайните (leaf) класове имат истински пакети, но виртуалното време
на междинните класове също се поддържа, като се сумира общия брой байтове,
използван от техните наследници.
Когато един пакет излиза от опашката, йерархичният scheduler на HSFC минава през
класовете от корена до един краен клас. На всяко ниво от йерархията scheduler-ът
избира класа с най-малко виртуално време измежду неговите наследници. Когато
бъде достигнат краен клас, той се и обслужва.
Обърнете внимание, че scheduler-ът търси само директни наследници на всяко ниво.
Ето защо разпределението на капацитета е пропорционално на кривините на
сервизните криви сред класовете с един родител, но не и сред такива с различни
родители. Например 4 крайни класа в следващата илюстрация ще получат еднакъв
капацитет, въпреки че А, B и C, D имат различни кривини.
С други думи, съотношението между класовете с един родител контролира
разпределението на капацитета, а абсолютните стойности на кривините нямат
значение. (Също стойностите на виртуалното време трябва да са логични само сред
класовете с един и същи родител).
root (100Mbps)
|
+-------+-------+
| |
E (20Mbps) F (20Mbps)
| |
+---+---+ +---+---+
| | | |
A B C D
(10Mbps) (10Mbps) (1Mbps) (1Mbps)
-
Планиране в реално време:
Противоположно на йерархичното планиране, за планирането в реално време се
използва едно единствено последователно време. Всеки клас пази кумулативен брой
байтове, подобен на общия брой байтове, но само за пакетите, които са били
подложени на планиране в реално време.
HFSC изчислява време за избиране и краен срок за всеки клас.
Времето за избиране и крайния срок са x-проекции на главата и опашката на
следващия пакет.
Един клас може да бъде избран за планиране в реално време, когато текущото време
стане по-голямо от времето за избиране на класа.
Планировчикът за реално време избира класа с най-малък краен срок сред
възможните.
bytes
| /
| /service curve
| /
next -->+ +----------------+
packet | | /|
length | | / |
| | / |
cumulative --> + +------------+ |
bytes | /| |
already | / | |
sent | / | |
/ | |
| |
| |
--------+---+--------------> time
eligible deadline
time
В оригиналния документ за HFSC за планирането в реално време и за
разпределението на капацитета се използва една сервизна крива. ALTQ (а оттам и
имплементацията за Linux) е разширена и може да използва независими криви за
реално време и за разпределение на капацитета.
Разделянето на сервизните криви позволява да се контролират независимо
гарантираната скорост и разпределението на излишния капацитет. Например възможно
е да се гарантира минимум капацитет 2Мбита на два класа, но излишния капацитет
на бъде разпределен в различно съотношение.
Възможно е също която и да е от сервизните криви да бъде установена на 0. Когато
кривата на реалното време е 0, класът получава само излишния капацитет.
Когато кривата на разпределението е 0, класът не може да получава излишен
капацитет при наличие на такъв. Обърнете внимание, че нулево разпределение прави
класа не work-conserving.
Забележете, че разпределението на капацитет може да гарантира заделената скорост
само ако кривата на реалното време е равна или по-малка от кривата на
разпределение на капацитет за всички класове. Ако кривата на разпределението на
капацитета е по-малка, скоростта може да не бъде осигурена.
Пишете ми, ако намерите грешки и/или несъответствия в този текст.
Abstract:
This is a brief memo, intented to help out in building a mail system comprised
of postfix as MTA, Courier-IMAP/POP3 and various other useful stuff like SASL2
user authentication, pop-before-smtp (whichever one chooses);
Amavisd-new/Spamassasing antivirus and spamchecking system; and finally MySQL
as a backend. In some places this little document is following almost by heart
the instructions found in different places the net, and especially the excellent
http://high5.net/howto
Installation of Postfix
The entire setup is performed on an (almost) fresh install Redhat Linux 7.3.
The Postfix version, used in this example is 2.0.13, and the appropriate
SSL/TLS patch version is 0.8.15-2.0.13-0.9.7b. Before initiating the postfix
installation itself, it is necessary to install several of the other
programmes, i.e. MySQL – I used the version shipped with RH 7.3, and the latest
BerkeleyDB from here:
http://www.sleepycat.com/download/index.shtml
Here I wont describe the compillation and setup of the above.
Go get the latest postfix source from one of the mirrors around the world:
http://www.postfix.org/download/
and the Postfix TLS patch:
ftp://ftp.aet.tu-cottbus.de/pub/postfix_tls/pfixtls-0.8.15-2.0.13-0.9.7b.tar.gz
tar zxf postfix-2.0.13.tar.gz
tar zxf pfixtls-0.8.15-2.0.13-0.9.7b.tar.gz
cd /usr/src/postfix-2.0.13
patch -p1 < <path to you pfix-tls patch>make makefiles 'CCARGS=-I/usr/include/mysql -DHAS_MYSQL \
-I/usr/local/include/sasl -DUSE_SASL_AUTH \
-I/usr/local/BerkeleyDB.4.1/include -DHAS_DB \
-I/usr/include/openssl -DUSE_SSL' \
'AUXLIBS=-L/usr/lib/mysql/ -lmysqlclient \
-lssl -lcrypto -lz -lm \
-L/usr/local/lib/sasl2 -lsasl2 \
-L/usr/local/BerkeleyDB.4.1/lib -ldb'
groupadd postdrop
groupadd postfix
useradd -g postfix postfix
make && make install
Configuration
Information on TLS setup is described here:
http://www.aet.tu-cottbus.de/personen/jaenicke/postfix_tls/
Create the database
Create a Postfix user and the Postfix database.
Use mysql or mysql -p to login to the MySQL Monitor.
USE mysql;
INSERT INTO user (Host, User, Password) VALUES
('localhost','postfix',password('postfix123'));INSERT INTO db (Host, Db, User,
Select_priv) VALUES ('localhost','postfix','postfix','Y');CREATE DATABASE
postfix;
Create the Tables
In order to use MySQL with Postfix we need to create 3 tables. All of
these tables have information for Postfix, and some for Courier-IMAP as
noted by each table. There are a couple of columns that are not used by
neither Postfix or Courier-IMAP. These columns are:
- domain (in some tables)
- create_date
- change_date
- active
These columns are used to make your life easier together with Postfix
Admin. The „active“ column is not used at the moment.
Create the Alias Table
#
# Table structure for table alias
#
USE postfix;
CREATE TABLE alias (
address varchar(255) NOT NULL default '',
goto text NOT NULL,
domain varchar(255) NOT NULL default '',
create_date datetime NOT NULL default '0000-00-00 00:00:00',
change_date datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(4) NOT NULL default '1',
PRIMARY KEY (address)
) TYPE=MyISAM COMMENT='Virtual Aliases–mysql_virtual_alias_maps';
Postfix is using the „address“ and „goto“ column.
Courier is not using this table.
NOTE: This table can be used for virtual .foward files. This table is nothing
more than /etc/aliases that you will find on any *nix-like OS.
Multiple destination email addresses need to be separated by a „,“ (comma).
Create the Domain Table
#
# Table structure for table domain
#
USE postfix;
CREATE TABLE domain (
domain varchar(255) NOT NULL default '',
description varchar(255) NOT NULL default '',
create_date datetime NOT NULL default '0000-00-00 00:00:00',
change_date datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(4) NOT NULL default '1',
PRIMARY KEY (domain)
) TYPE=MyISAM COMMENT='Virtual Domains–mysql_virtual_domains_maps';
Postfix is using the „domain“ and „description“ column.
Courier is not using this table.
Create the Mailbox Table
#
# Table structure for table mailbox
#
USE postfix;
CREATE TABLE mailbox (
username varchar(255) NOT NULL default '',
password varchar(255) NOT NULL default '',
name varchar(255) NOT NULL default '',
maildir varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
create_date datetime NOT NULL default '0000-00-00 00:00:00',
change_date datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(4) NOT NULL default '1',
PRIMARY KEY (username)
) TYPE=MyISAM COMMENT='Virtual Mailboxes–mysql_virtual_mailbox_maps';
Postfix: is using the „username“ and „maildir“ column.
Courier: is using the „username, „password“, „name“ and „maildir“ column.
Populate the Tables
USE postfix;
INSERT INTO domain (domain,description) VALUES ('domain.tld','Test Domain');
INSERT INTO alias (address,goto) VALUES ('alias@domain.tld','user@domain.tld');
INSERT INTO mailbox (username,password,name,maildir) VALUES
('user@domain.tld','$1$DOrHOomo$U6MleaFKGwWLB3iS9P1Yx0','Mailbox
User','user@domain.tld/');
The first INSERT is to let Postfix know that this domain is a virtual
domainand should be handled by Postfix. It’s also possible to have everything in
one table but probably this way it’s nicer.
The second INSERT is a virtual alias pointing to the third INSERT.
The third INSERT is the actual virtual mailbox, as you can see here
it’s used MD5 password for backward compatibility with local defined mail
accounts. If you are using MD5 passwords, make sure you don’t use the builtin
MySQL routine to generate MD5 passwords. This is not compatible with
Courier-IMAP. If you want you can also use cleartext or encrypted passwords.
To make sure that the new MySQL users are working, do the following
from the command line:
$ mysqladmin reload
Postfix Install
You have to create a directory to have all your virtual users mail dropped in,
this directory needs to be owned by Postfix.
Postfix Setup
main.cf
The below example is the part that goes into your main.cf file of Postfix. The
path to the mysql files might be different on your setup. The same might be for
uid_maps, gid_maps and minimum_uid values. These
values should be the ones from the postfix user and group. You can find these
in your /etc/passwd file.
virtual_alias_maps = mysql:/etc/postfix/mysql_virtual_alias_maps.cf
virtual_gid_maps = static:12345
virtual_mailbox_base = /virtual
virtual_mailbox_domains = mysql:/etc/postfix/mysql_virtual_domains_maps.cf
virtual_mailbox_maps = mysql:/etc/postfix/mysql_virtual_mailbox_maps.cf
virtual_mailbox_limit = 51200000
virtual_minimum_uid = 12345
virtual_transport = virtual
virtual_uid_maps = static:12345
$ mkdir /virtual
$ chown -R postfix:postfix /virtual
$ chmod -R 751 /virtual
mysql_virtual_alias_maps.cf
You will need to put this into a text file for postfix to pickup.
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
table = alias
select_field = goto
where_field = address
mysql_virtual_domains_maps.cf
You will need to put this into a text file for postfix to pickup.
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
table = domain
select_field = description
where_field = domain
mysql_virtual_mailbox_maps.cf
You will need to put this into a text file for postfix to pickup.
user = postfix
password = postfix123
hosts = localhost
dbname = postfix
table = mailbox
select_field = maildir
where_field = username
Postfix Admin
Here you can find information on the excellent tool PostfixAdmin that Mischa
Peters has written in PHP. It’s in production at least 2 sites that he maintains,
and at a couple of sites tham I’m administering. If you want to install this
make sure that you have a running webserver that handles PHP correctly and is
able to handle .htaccess fiels. Here you wont find any instrucions on your
webserver/PHP install.
Postfix Admin is a way to give virtual domain owners total control over
their domains.
Postfix Admin Download
You can get PostfixAdmin here:
http://high5.net/postfixadmin/
Postfix Admin Install
Unpack Postfix Admin in the directory where you want it. For example:
/var/www/html/<site>/pfadmin. There is also an Admin Admin part, change
directory to the „admin“ directory and sue some authentication or other
means for controlling access to this dir.
Some other information that you might want to look at is in the
site_lib.php file.
In order to be able to read and write from the database I have created a
seperate user in MySQL. I do this because Postfix Admin needs to have
more rights on the Postfix database. If you are worried about the
password for the database. I have Postfix Admin running as the
WebServer owner
:group, that way your postfix username and password are
somewhat protected against local users.
USE mysql
INSERT INTO user (Host, User, Password) VALUES
('localhost','postfixadmin',password('postfixadmin123'));INSERT INTO db (Host,
Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv) VALUES
('localhost', 'postfix', 'postfixadmin', 'Y', 'Y', 'Y', 'Y');
Make sure you reload MySQL.
$ mysqladmin reload
Postfix Admin Setup
In order to use Postfix Admin you have to add another table to the
Postfix database.
#
# Table structure for table admin
#
USE postfix;
CREATE TABLE admin (
username varchar(255) NOT NULL default '',
password varchar(255) NOT NULL default '',
domain varchar(255) NOT NULL default '',
create_date datetime NOT NULL default '0000-00-00 00:00:00',
change_date datetime NOT NULL default '0000-00-00 00:00:00',
active tinyint(4) NOT NULL default '1',
PRIMARY KEY (username)
) TYPE=MyISAM COMMENT='Virtual Admins–Store Virtual Domain Admins';
Postfix Admin Usage
Once you have done all this you can take your browser and browse to the
location where you have Postfix Admin installed. Goto the admin part first in
order to put some real domains that you host in the database. This will be
http://your.domain.tld/postfixadmin/admin. The default login is admin
/ admin.
Cyrus SASL2 install and config
For user authentication one can choose between several methods, of which SASL
is probably the best regarding security. From users’ perspective, though,
pop-before-smtp is easier to work with.
SASL2
http://asg.web.cmu.edu/cyrus/download/
There are two ways for using SASL2 authentication – one is through PAM, which is
fairly easy to setup, though probably not so scalable, and the other is
directly through auxprop.
./configure --with-bdb-libdir=/usr/local/BerkeleyDB.4.1/lib \
--with-bdb-incdir=/usr/local/BerkeleyDB.4.1/include --with-openssl \
--enable-login --with-ldap --with-mysqlmake
SASL2 auth through PAM/MySQL
http://pam-mysql.sourceforge.net/
/etc/pam.d/smtp
auth required pam_mysql.so user=postfix passwd=postfix123 db=postfix
table=mailbox usercolumn=username passwdcolumn=password crypt=1
account required pam_mysql.so user=postfix passwd=postfix123 db=postfix
table=mailbox usercolumn=username passwdcolumn=password crypt=1
You HAVE to use the full email address as username, or else auth will fail. In
the given setup, though, you can use the name itself by selecting
usercolumn=name.
NB: This works, but is NOT fully tested.
SASL2 through auxprop
In /usr/local/lib/sasl2/smtpd.conf:
mech_list: plain login
pwcheck_method: auxprop
auxprop_plugin: mysql
mysql_user: postfix
mysql_passwd: postfix123
mysql_hostnames: junip3r.mnet.bg
mysql_database: postfix
mysql_statement: "SELECT %p FROM mailbox WHERE username = '%u' and domain =
'%r'"#mysql_verbose: yes
Note that in main.cf of postfix’s configuration we are setting
„smtpd_sasl_local_domain = <NULL>“, i.e. empty value. For this reason we have
to select on ‘name’ and not on ‘username’.
NB: If you change any of the mechs or the contents of smtpd.conf, make sure to
do a ‘postfix reload’, because there’s some kind of caching, obviously.
Finally: NOT WORKING! Auxprop doesnt want to send the correct realm,
i.e. domain. Have to investigate further.
POP-before-SMTP
Here you can use ONE OF:
POP before SMTP
The setup of POP-before-SMTP is fairly
easy, compared at least with the other software described here. Following the instructions on the web page I was able to set it up in a matter of 2 minutes. You just have to uncoment the line:
$file_tail{'name'} = '/var/log/maillog';
and add this line, in order our setup to work with courier 2.0.0:
$pat = '^(... .. ..:..:..) \S+ (?:imapd-ssl|pop3d-ssl|imapd|pop3d):
LOGIN, user=\S+, ip=\[\:\:ffff\:(\d+\.\d+\.\d+\.\d+)\].*';
then you can change the grace period if you like. Default is 30 minutes, which
is fairly long, IMHO.
$grace = 30*60;
DRAC
http://mail.cc.umanitoba.ca/drac/
WHOSON
http://whoson.sourceforge.net/
As a matter of simplicity probably popbsmtp is the best, since it is a
single daemonized perl script watching the mail logs, and DRAC needs
that the POP daemon used has to be recompiled. DRAC and WHOSON are not
tested in this setup.
Courier-IMAP install and config
Do a
tar jxf courier-imap-2.0.0.tar.bz2 -C /home/nikky/src
./configure --sysconfdir=/etc/courier
will do the job. Then
$ make && make check
$ su root
# make install
authmysqlrc
NOTE: Make sure that there are no (trailing) spaces in this file, only
tabs!!
Below is part of the authmysqlrc file that is relevant to our setup.
The things that you might need to change are the mysql_password,
mysql_uid and mysql_gid.
MYSQL_CRYPT_PWFIELD password
MYSQL_DATABASE postfix
MYSQL_OPT 0
MYSQL_SERVER junip3r.mnet.bg
MYSQL_USERNAME postfix
MYSQL_USER_TABLE mailbox
MYSQL_PASSWORD postfix123
MYSQL_UID_FIELD '12345'
MYSQL_GID_FIELD '12345'
MYSQL_HOME_FIELD '/virtual'
MYSQL_LOGIN_FIELD username
MYSQL_MAILDIR_FIELD maildir
MYSQL_NAME_FIELD name
Read the hints if you have trouble logging in:
Make sure that there are NO spaces in the authmysqlrc file, only tabs. Make
sure that there are only single quotes ‘ around static values like
'/virtual', 'UID', 'GID'. NO single quotes around
localhost! Make sure that localhost exists in your /etc/hosts file.
Including IPv6 during the compilation could cause a problem. The
MYSQL_GID_FIELD and MYSQL_UID_FIELD are for the
UIDand GID of the postfix user and group, NOT for the MySQL
user andgroup.
Amavisd/Spamassassin/F-Prot install and config
amavisd-new is a high-performance interface between message transfer agent
(MTA) and one or more content checkers: virus scanners, and/or SpamAssasin.
http://www.ijs.si/software/amavisd/
Specific information on installing Amavisd-new on Redhat can be found
here:
http://www.rmorales.com.ar/rpms/amavis/
perl -MCPAN -e shell is your friend!
In this example we are using the home version of F-Prot, which is a
non-daemonised command line virus scanner, used for checking files and
triggering the necessary alerts. You can download it from here: http://www.f-prot.com/download/download_fplinux_personal.html
The installation of the three flavours (RPM,DEB and TGZ) is fairly
straight-forward and does not need any instructions.
Links
http://small.dropbear.id.au/myscripts/postfixmysql.html