среда, 22 августа 2012 г.

Python MIME-библиотека и строка From в Unix-стиле



При создании тела письма с помощью питоновского класса email.message.Message (и его потомков типа email.mime.base.MIMEBase или email.mime.multipart.MIMEMultipart) первой строкой автоматически добавляется  знакомая каждому старому юниксоиду строка From без двоеточия.
Например:

$ python
>>> import  email.mime.multipart
>>> msg = email.mime.multipart.MIMEMultipart()
>>> print msg

From nobody Wed Aug 22 11:02:28 2012
Content-Type: multipart/mixed; boundary="===============1046125271=="
MIME-Version: 1.0

--===============1046125271==

--===============1046125271==--

Конечно всякий нормальный емейл-клиент реагирует на эту строку спокойно: ведь она существует в мире уже третий десяток лет, но - увы - современный мир полон ненормальными почтовыми клиентами. В одном из их - Lotus Notes 8.5.1 - наличие строки From в заголовке приводит к тому, что MIME-структура письма не отображается - и письмо выводится как простой текст.   
Как заставить Message не включать в письмо данную строку? В документации обнаружено два способа:
  1. прямой. Message имеет метод as_string(self, unix_fromline=False). Если в прошлом примере вместо print msg сделать print msg.as_string() (или - для не надеющихся на умолчательное поведение - print msg.as_string(False)), то мы получим текст сообщения без строки From.
  2. прикольный. Строку From можно заменить любой своей строкой - для этого у нашего класса есть метод set_unixfrom(self, string). Т.к. по стандарту мы можем беспрепятственно добавлять в письмо любые заголовки, начинающиеся с "X-", то сделав что-то типа: msg.set_unixfrom("X-Mailer: Python Is Not Lotu$ Note$") мы получим тело письма, которое ничем не смутит нашего капризного клиента. 

среда, 15 августа 2012 г.

Заработавший rp_filter в CentOS 6.3

Продолжающиеся разборки со свежеустановленной CentOS 6.3 принесли новые неожиданные результаты. Примерная конфигурация такая:
Компьютер администратора имеет ip-адрес 10.1.1.101 в сети 10.1.1.0/24;
Сервер (как раз CentOS 6.3 x86_64) имеет интерфейс eth0 адресом 10.1.1.201 в той же сети и eth1 адресом 10.1.2.201 в сети 10.1.2.0/24.
Маршрутизация между этими сетями настроена, с роутера все три адреса успешно пингуются.
С компьютера администратора пингуется 10.1.1.201, но никак не пингуется 10.1.2.201.
В принципе такое поведение нельзя назвать неправильным - на интерфейсе eth1 оказывается пакет, который по всем правилам должен был прийти на eth0 - и ответа на него не посылается. Другое дело, что за прошлую жизнь админ так привык к неправильному поведению, что правильное ему кажется неудобным. Поиск по настройкам sysctl достаточно скоро находит виновного:
net.ipv4.conf.eth1.rp_filter = 1
Из документа http://linuxgazette.net/issue77/lechnyr.html как раз и явствует что:
The rp_filter can reject incoming packets if their source address doesn't match the network interface that they're arriving on, which helps to prevent IP spoofing.
Установка:
net.ipv4.conf.eth1.rp_filter = 0
приводит к тому, что желанный пинг появляется.
А напоследок - как всегда - самое смешное. В CentOS 5-ой ветки, на которых автор этих строк собственно и успел пристраститься к "неправильным" пингам, установки net.ipv4.conf.*.rp_filter по умолчанию - точно такие же, как и в 6.3. Только не вызывают они заявленного поведения. Одно из двух - либо давно объявленную фичу наконец-то заставили работать, либо где-то таится еще какая-то настройка, которая говорит системе, реагировать ей на rp_filter - или нет.

вторник, 14 августа 2012 г.

Неуловимый LANG в CentOS 6.3

При установке CentOS 6.3 с образа minimal меня удивили сообщения на русском языке (при установке был явно выбран английский). Переменная LANG действительно содержала ru_RU.UTF-8, но рекурсивный поиск в /etc и $HOME не давал ответа, каким образом подобное значение устанавливается - такой подстроки просто-напросто не было в файлах этих директорий. Проблема выглядела невероятной, пока не был произведен рекурсивный поиск слова LANG. Ответ нашелся в файле /etc/ssh/sshd_config:
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE \\
 LC_MONETARY LC_MESSAGES
(Это одна строка - переноса в оригинальном файле нет)
Т.е. получается, что установки языка передавались на сервер с моего компьютера по ssh. Действительно, если убрать LANG из этой строки, то при следующем входе в систему языком сообщений делается английский.
Следует добавить, что аналогичные настройки имеются и в клиентском файле /etc/ssh/ssh_config:
SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE \\
LC_MONETARY LC_MESSAGES
Так что, вероятно, наиболее правильным решением проблемы является как раз изменение SendEnv на том компьютере, откуда производится вход по ssh - а то вдруг другие администраторы сервера захотят видеть русский интерфейс? Хотя - с другой стороны - а что им мешает явно установить LANG в своих профайлах?
Ну а самое смешное заключается в том, что данная строка имеется в /etc/ssh/sshd_config и в более ранних версиях CentOS (например, в 5.3) - но там она почему-то никак на язык консольных сообщений не влияет.