mini-notes-issue-3/

Что-то давно я не делился своими мини-заметками. За прошедшее время их накопилось довольно много, так что мне пришлось отобрать только лучшие из них. По моему субъективному мнению, конечно. Кому интересно, может ознакомиться предыдущими выпусками — под номером один и два .

1. SSH-форвардинг

Как нам хорошо известно, SSH позволяет не только удаленно управлять машиной, но и передавать файлы . Еще одна интересная возможность этого протокола — перенаправление портов. Вот как я использую это на практике.

Пример первый — использование SSH-сервера в качестве прокси:

# кусок ~/.bashrc
alias ircproxy = »
while [ true ] ; do
ssh -N -L 31337:irc.rusnet.ru:9997 user@host
sleep 10;
echo ‘reconnecting…’;
done
»

Общаясь в IRC-чатах , вы светите свой IP. Возможно, я параноик, но мне не кажется хорошей идеей сообщать тысячи незнакомых людей, на какой улице я живу. Для скрытия IP обычно используются прокси, но хорошие (быстрые и долгоиграющие) прокси найти очень сложно. А платить за абузоустойчивый VPN или Socks5 на протрояненых машинах аморально и жаба душит.

А вот найти недорогой или даже халявный SSH намного проще. В данном примере предполагается, что после использования алиаса ircproxy юзер будет коннектится на локальный порт 31337. Весь трафик будет передаваться хосту host, а оттуда — на irc.rusnet.ru:9997 (и обратно). Короче — получаем проксю. Бесконечный цикл в алиасе сделан на случай временных проблем в работе сети.

Для удобства следует настроить идентификацию с помощью identity file . Описанный прием также работает для электронной почты, различных IM и веб-сайтов (включая https). Короче, для всего. А если в качестве целевого хоста указать HTTP/Socks прокси, можно получить натуральный VPN! Если поднимать свой сокс-сервер неохота, можно залить на хост какой-нибудь анонимайзер . Мне, к примеру, нравится PHProxy .

Дополнение: Как подсказал в комментах Anatoly Kern, можно сделать проще:

ssh -N -D localhost: 3111 user @ host

Проверяем проксю:

curl —socks5 localhost: 3111 http: // ip.xss.ru /

Пример второй — использование SSH для обхода NAT:

# кусок ~/.bashrc
alias sshbackdoor = »
while [ true ] ; do
ssh -N -R 31337:localhost:22 user@host
sleep 10;
echo ‘reconnecting…’;
done
»

Здесь все аналогично первому примеру с точностью до наоборот. Порт 31337 на хосте host переадресовывается на порт 22 клиентской машины. Представим, что на этом порту крутится SSH, а клиент находится за NAT’ом. Тогда можно откуда угодно зайти на host, сказать:

ssh -p 31337 username @ localhost

… и попасть на клиентскую машину! Только предварительно следует ее правильно настроить. У меня всюду используется Фряха , потому настройку я произвожу так. Сначала прописываю в /etc/rc.conf:

sshd_enable=»YES»

Затем в /etc/ssh/sshd_config:

# принимаем соединения только с этого адреса
ListenAddress 127.0.0.1

И, наконец, запускаю sshd:

/ etc / rc.d / sshd start

Если планируется часто управлять машиной через SSH, советую работать в screen и использовать побольше консольных утилит типа rtorrent и alpine. Тогда не придется возиться с настройкой VNC. Это, конечно, штука хорошая, но медленная и лично мне кажется не очень удобной.

2. Как сделать редирект средствами HTML и JavaScript

Да, иногда приходится так извращаться:

< html >
< head >
< title > 301 moved permanently < / title >
< meta name = «robots» content = «noindex» >
< meta http-equiv = «refresh» content = «0;url=http://example.ru/goto.html» >
< / head >
< body >
<!— <a href=»http://example.ru/goto.html»>Moved permanently</a> —>
< script type = «text/javascript» > <!—
document.location = «http://example.ru/goto.html»;
// —> < / script >
< / body >
< / html >

Тут все довольно просто, так что no comments.

3. Скрипт для мониторинга сайтов

Если у вас много сайтов, вам наверняка хотелось бы быть в курсе, когда один из них становится недоступным. У меня несколько сайтов, которые я мониторю следующим скриптом:

#!/usr/bin/perl
use strict ;

# site-monitor.pl script
# (c) Alexandr A Alexeev 2011 | http://remontka.com/

my %sites = (
‘cba7746c2ad067c8’ => ‘http://site1.example.ru/’ ,
’47a4dff54e61e8a2′ => ‘http://site2.example.ru/’ ,
) ;

my $adm_mail = ‘admin@example.ru’ ;
my $mailer = «mail» ; # mutt
my $sleep = 5 ; # minutes
my %uptime_from ; # uptime_from{url} = sec

chomp ( my $start = `date +%s` ) ;
$uptime_from { $sites { $_ } } = $start
for ( keys %sites ) ;

while ( 1 ) {
chomp ( my $date = `date ‘+%Y-%m-%d %H:%M’` ) ;

for my $hash ( keys %sites ) {
my $url = $sites { $hash } ;
$hash = quotemeta $hash ;

my $str = `wget -q ‘$url’ -O -` ;
my $report = «[$date] wget returns $?, url: $url» ;

# вычисляем аптайм
chomp ( my $now = `date +%s` ) ;
my $uptime = $now $uptime_from { $url } ;

# приводим аптайм понятный человеку вид
my $s = $uptime % 60 ;
$uptime = int ( $uptime / 60 ) ;
my $m = $uptime % 60 ;
$uptime = int ( $uptime / 60 ) ;
my $h = $uptime % 24 ;
$uptime = int ( $uptime / 24 ) . «d ${h}h ${m}m ${s}s» ;

$report .= «, uptime: $uptime» ;

unless ( $str =~ /$hash/ ) { #   && !$?) {
$uptime_from { $url } = $now ;

`echo «$report» | $mailer -s «$url is down» $adm_mail` ;
print «!!! » ;
}
print «$report n » ;
}
sleep ( $sleep * 60 ) ;
}

Строки типа cba7746c2ad067c8 нужно прописать в комментариях после </html> в подвале проверяемой страницы. Сгенерировать такой ID можно, например, этой командой:

cat / dev / urandom | head -c 4096 | sha256 | head -c 16 && echo

Проверять код ответа сервера недостаточно, потому что он может быть и правильным, когда страница на самом деле сообщает об ошибке или вообще ничего не содержит. Помните также, что если у вас на сайте используется кэширование страниц, вы можете не отлавить падение БД.

4. Горячие клавиши Xfce

Мне нравится Xfce за его простоту и скорость работы. А еще в нем предусмотрены очень удобные сочетания клавиш, позволяющие управлять окнами практически без использования мыши:

Alt + TAB   Переключение между окнами
Alt + SPACE Открыть меню со списком операций над текущим окном
Alt + F2    Выполнить команду
Alt + F4    Закрыть окно
Alt + F6    Показывать окно на всех рабочих местах
Alt + F7    Переместить окно
Alt + F8    Изменить размер окна
Alt + F9    Свернуть окно
Alt + F10   Свернуть/развернуть окно во весь рабочий стол
F11         Свернуть/развернуть окно во весь экран
Alt + F12   Вкл/выкл отображение окна поверх всех окон
Ctr + F##   Перейти на рабочее место номер ##

Список, разумеется, не полон.

5. Генератор страницы с облаком меток для WordPress

Одно время я искал плагин для WordPress, позволяющий создать страницу (не виджет) с облаком меток. Ничего толкового не нашлось, так что я набросал вот такой небольшой скрипт:

#!/usr/bin/perl

# WordPress Tag Page Generator v 1.0
# (c) Alexandr A Alexeev 2011 | http://remontka.com/

# Usage: ./tags.pl | mail -s ‘tag cloud’ user@example.ru

use strict ;
use DBI ;
use List :: Util qw/shuffle/ ;

my $db = DBI -> connect (
«dbi:mysql:blog_db:locahost» , «db_user» , «db_pass» ,
{ PrintError => 0 , RaiseError => 0 }
) or die «ERROR: $! n » ;

my $prefix = «wp_» ;
my $limit = 250 ;
my $tag_url = «/tag/» ;

my $query = qq {
select
count ( distinct r . object_id ) as cnt ,
t . name ,
t . slug
from
$ { prefix } terms as t
left join
$ { prefix } term_relationships as r
on r . term_taxonomy_id = t . term_id
left join
$ { prefix } term_taxonomy as tt
on t . term_id = tt . term_id
where
tt . taxonomy = ‘post_tag’
group by t . name , t . slug
order by cnt desc
limit $limit
} ;

my $res = $db -> prepare ( $query ) ;
$res -> execute ( ) or die «Query failed: n n $query» ;
my $max ;
my @lines ;
while ( my ( $cnt , $tag , $slug ) = $res -> fetchrow_array ( ) ) {
$max = $cnt unless ( defined ( $max ) ) ;
my $percent = 100 + int ( 100 *$cnt / $max ) ;
push @lines , «<a href=’$tag_url$slug/’ style=’font-size: $percent % ;’>$tag</a>» ;
}
print join » » , shuffle @lines ;

Тут все тривиально.

6. Красивый вывод меток, присвоенных посту

Я активно пользуюсь метками в этом блоге, но места для их вывода в начале поста дизайнер шаблона отвел довольно мало. Разумным компромиссом в данном случае мне кажется вывод только первых N символов меток. А точнее — первых M меток, суммарная длина которых (вместе с разделителями) не превышает N символов. Вот как это у меня реализовано:

<div class=»postmetatags»> <?php the_time ( ‘Y-m-d’ ) ?> | Категории: <?php
$posttags = get_the_tags ( ) ;
$len = 0 ; $maxlen = 54 ;
$printtags = array ( ) ;
if ( $posttags ) {
foreach ( $posttags as $tag ) {
$len += 2 + mb_strlen ( $tag -> name , ‘UTF-8’ ) ;
if ( $len > $maxlen ) break ;
$printtags [ ] = ‘<a href=»‘ . get_tag_link ( $tag -> term_id ) . ‘»>’ .
$tag -> name . ‘</a>’ ;
}
}
if ( $len > $maxlen ) $printtags [ ] = «…» ;
echo join ( «, » , $printtags ) ;
?>
</div>

Число N можно подобрать, вписав длинную последовательность символов типа «ф» или «ш» (зависит от шрифта) в то место шаблона, где должны выводиться метки. Число уместившихся в одну строку символов минус 3 (под троеточие) и есть N.

7. Оптимизация заголовков страниц в WordPress

А еще в некоторых шаблонах плохо реализован вывод title. Исправить это поможет следующий код:

<title> <?php
wp_title ( is_archive ( ) ? » : ‘|’ , 1 , ‘right’ ) ;
if ( is_archive ( ) ) echo » | » ;
if ( $paged ) { echo «Страница $paged | » ; }
bloginfo ( ‘name’ ) ;
?> </title>

И никакие плагины с их фильтрами не нужны!

8. Как ваш e-mail попадает в спам-базы

Скрипт из заметки Как написать своего паука только обходит страницы, ничего с ними не делая. Вот пример полезной нагрузки (payload), собирающий адреса электронной почты:

my $at_regexp = ‘(?:s{0,8}(?:@|([^),;:]{0,16})|[[^];,:]{0,16}]|{[^},;:]{0,16}})s{0,8})’ ;
my @emails = $data =~ /([a-z0-9_][a-z0-9.-_]{3,32}$at_regexp[a-z0-9][a-z0-9.-]{3,32})/ig ;
@emails = grep { /.(ru|su|com|net|org|info|biz|name|me)$/i } @emails ;
s/$at_regexp/@/ for ( @emails ) ;

open FID , «>>./emails/list-$$.txt» ;
print FID «$_ n » for ( @emails ) ;
close FID ;

Вот почему публикация электронной почты в сети, даже с заменой собаки на «(at)» и прочими ухищрениями, практически наверняка обеспечивает попадание вашего мыла в чей-то спам-лист.

9. Получаем полный список доменов в зонах RU, SU и РФ

Оказывается, все до неприличия просто:

wget https: // partner.r01.ru / ru_domains.gz -O ru_domains.gz
wget https: // partner.r01.ru / su_domains.gz -O su_domains.gz
wget https: // partner.r01.ru / rf_domains.gz -O rf_domains.gz

Это обыкновенные текстовые файлы, сжатые gzip’ом. Каждая строка состоит из 6 полей, разделенных табуляцией. Поля эти следующие: домен, регистратор, created, paid till, free date, делегирован ли домен. Базы обновляются ежедневно примерно в 10:10 утра.

Как всегда, если кому есть что добавить к написанному, я буду рад вашим комментариям.

Дополнение: Мини заметки — выпуск 4

EnglishRussianUkrainian