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

четверг, 18 марта 2010 г.

Дискриминация по национальному признаку или баним страны.

Так получилось, что понадобилось прикрыть доступ к серверу из некоторых стран. Понимаю, что кровавая гебня и всё такое, но задача есть, надо сделать.
Вот здесь находим архивчик с базой IP-адресов и их национальной принадлежностью. Далее за нас работает небольшой скрипт:
#!/bin/bash
#
TMPDIR=/tmp/geoiptban
IP_BBASE=$TMPDIR/bbase.csv
IP_EBASE=$TMPDIR/ebase.csv
DB_ZIP=$TMPDIR
PERL=/usr/bin/perl
FILE_BCOUNTRY=$1
COUNTRY_DB_URL=http://geolite.maxmind.com/download/geoip/database/GeoIPCountryCSV.zip
mkdir -p $TMPDIR
# Стягиваем и распаковываем базу айпишников.
wget -q -O $DB_ZIP $COUNTRY_DB_URL
unzip -p $DB_ZIP > $IP_BBASE
# Убираем лишние символы из базы, для простоты обработки.
if [ -e "$IP_BBASE" ]
then
        cp $IP_BBASE $IP_EBASE
        $PERL -pi -e 's/"//g' $IP_EBASE
else
        echo "Source ip-base-file not found."
        exit 0;
fi
# Обработка базы. Форматируем базу сперва в вид диапазонов ip-адресов, а потом в список подсетей.
# Получившиеся подсети скармливаем iptables'у.
if [ -e "$FILE_BCOUNTRY" ]
then
        for country in $(cat ${FILE_BCOUNTRY})
        do
                grep $country $IP_EBASE | awk -F "," '{print $1," - ",$2}' > $TMPDIR/$country.il
                for ((i=1;i<=$(wc -l ${TMPDIR}/${country}.il | awk '{print $1}');i++))
                do
                        ipcalc $(head -n ${i} ${TMPDIR}/${country}.il | tail -n 1) | grep -v deaggregate >> $TMPDIR/$country.nl
                done
        done
        for country_network_list in $(ls ${TMPDIR} | grep nl)
        do
                for ((i=1;i<=$(wc -l ${TMPDIR}/$country_network_list | awk '{print $1}');i++))
                do
                        iptables -t filter -A INPUT -s $(head -n ${i} ${TMPDIR}/$country_network_list | tail -n 1) -j DROP
                done
        done
else
        echo "List of blocked countries not found."
        exit 0;
fi
rm -rf $TMPDIR
Для определения списка стран, которые надо забанить используется файл, в котором просто перечисляются их коды:
[root@gateway ~]# cat country_list
RU US GB
Запускается скрипт очень просто:

[root@gateway ~]# ./geoiptban.sh country_list

пятница, 29 января 2010 г.

Gentoo

Наконец собрался написать про Gentoo.
Давно хотел попробовать этото дистрибутив в работе. Я его, конечно, пробовал до этого, но так, мельком. Пару раз ставил, пару раз настраивал, но со временем забрасывал. Потом так получилось, что пришлось повозиться с уже установленной системой, которую надо было довести до ума. Как это всегда бывает, система попалась полумёртвая и восстанавливать её приходилось долго и непросто. Но в процессе этого восстановления я открыл для себя некоторые довольно интересные вещи. Тогда-то и появилась мысль взяться за этот дистрибутив серьёзно. Порывшись в куче старого железа был извлечён винт на сосрок гигов, закуплено кофе и запланированы пару спокойных ночей. В итоге - ура. На компе в качестве второй системы(рядом с родным Debian Lenny) стоит Gentoo. Но как-то всё тоже выходило неудачно. То иксы криво стартовали, то софт при компиляции ошибки выдавал, то ещё какие-нибудь косяки и никак не хватало времени довести до ума. Но за несколько дней до Нового Года, наконец, время позволило взяться за Gentoo серьёзно...
И вот, в новый 2010 год я вошёл, имея на компе стабильную gentoo с kde4.
Как у меня всегда бывает, вышло несовсем гладко. То забывал нужный драйвер в ядро вкомпилить, то USE-флаги криво выставлял, но так или иначе, сейчас могу сказать честно: новой системой я доволен.
А теперь несколько подробностей.
Ну, во-первых:
[cppmm@damned ~]$ uname -a
Linux damned 2.6.31-gentoo-r6-cppmm-v7 #1 SMP Fri Jan 29 07:25:45 NOVT 2010 x86_64 AMD Athlon(tm) 64 X2 Dual Core Processor 5600+ AuthenticAMD GNU/Linux

Да, как можно заметить, нормальное ядро удалось собрать только с седьмой попытки. И тут дело исключительно в моей невнимательности. Собственно, последняя пересборка понадобилась потому что неправильно были выставлены опции кодировок для файловой система FAT, из-за чего флешки либо монтировались криво, либо вообще отказывались подключаться.
Впечатления от системы хорошие. Когда говорят, что gentoo работает быстро - можете смело верить. Это действительно так. Например, даже со стандартным init'ом загрузка до рабочего стола проходит буквально за несколько секунд. При этом, я решил попробовать не старую добрую крысу(xfce4), а kde. И если раньше у меня было впечатление, что кеды - это что-то монструзно-торзмонутое, то тут всё совсем не так. Весь софт прямо сказать летает. Кроме всего прочего, раз уж стоят кеды, я  решил и софт использовать исключительно qt'шный.
Плеер: По-умолчанию в kde4 идёт JuK. Штука до безобразия простая, малофункциональная(даже по моим меркам). Немного повспоминав мандривовскую молодость было принято решение поставить amarok... Я даже не ожидал, насколько он стал хорош! Ну, старых проблем с кодировками тегов у меня быть не могло - все теги давно сконвертированы в utf. А вот интерфейс порадовал. Теперь он действительно удобен. Один раз задав пути к библиотеке, я забыл про мучительный поиск нужной песни и добавление её руками. Так же очень порадовала фишка с прикрученной википедией. Да-да. Когда я запускаю песню, amarok автоматом идёт в инет на википедию, и стягивает описание исполнителя. Ну и кроме этого он ещё откуда-то вытягивает текст песни и обложку. Если с описанием - это так, свистелки, то текст песни оказался как нельзя кстати. Очень удобно. Выглядит это всё примерно так:
 
 С видео-проигрывателем получилось практически так же. Дефолтный dragonplayer как-то неинтересн. Но память подсказала, что был когда-то неплохой kaffeine. Он тоже стал удобнее и функциональнее. Кушает всё, работает с dvd-меню и вообще в принципе устраивает во всём. Один раз, правда, он отказался играть хороший фильм(точнее, фильм играл, а вот звука не было). Поставил SMPlayer(фронтенд к mplayer), но тот тоже отказался. Попытка воспроизвести этот же фильм на другой системе, а потом и на другом компе показала, что проблема не в плеерах, а в самом фильме. :)
Теперь о интернет-приложениях. Вот что, по-моему, осталось таким же, как и много лет назад, так это konqueror. Как был кривоват, так и остался. :)
Пришлось компилять firefox. Всё бы хорошо, но gtk-ашная лиса смотрится в qt-окружении убого. Но, это лечится. Нужно сперва поставить x11-themes/gtk-engines-qtcurve, который несколько облагораживает гткшный софт. А для совсем эстетов, у лисы есть замечательный плагин Personas. Там есть множество разнообразных тем и украшений. И теперь моя лиса выглядит так:
 
 В качестве jabber-клиента был оставлен старый-добрый psi. А точнее, его модификация psi+(кстати, вот тут вот и проявляется одна из фишек гентушных портажей - при помощи простейших манипуляций, я ставлю софт нужной мне версии с нужным мне функционалом, не заморачиваясь сборкой пакета).
Единственное, что пока не радует, это irc-клиент. Привычный xchat как-то тут не понравился, но я решил попробовать что-нибудь kde'шное, а именно kvirc. Не, клиент очень неплохой. Но настроек у него.... Тьма! До сих пор до конца ещё не донастроил. :) Но работать можно.
Остальное всё использую родное kde'шное, не особо заморачиваясь.
На обслуживание системы много времени не уходит. Я это, в принципе, и раньше знал, но повторюсь для особо упёртых. Если один раз всё настроить, в дальнейшем обновления можно делать на автомате. Главное не допускать глупых ошибок. К примеру, если хочется изменить USE-флаги у какого-либо приложение, не стоит это делать на лету. Для этого есть специальный файлик в /et/portage/. Там же, кстати, можно очень удобно маскировать ненужные пакеты, управлять зависимостями и вообще делать со своей системой всё, что душе угодно.
В дальнейших планах разобраться с написанием своих ebuild'ов для сборки собственных пакетов(например, недавно вышел vacuum im 1.0.0 - очень хочется попробовать, но в репах пока его нет). 

Разумеется, этот переход на домашнем десктопе совершенно не значит, что я резко переметнулся из стана Debian'щиков в gentoo'шники. Нет. На нетбуке всё тот же lenny. Ну и на рабочем компе ничего не изменится в ближайшее время. А то, что лучшей системой для серверов является debian меня вряд ли кто-нибудь когда-нибудь переубедит. Всё это просто значит, что linux'ы бывают разные и многие из них хороши. А если есть желание разобраться и какие-то базовые знания, то пойдёт любой дистрибутив(за исключением всяких ubuntu :)).
И на последок общий вид рабочего стола:

вторник, 17 ноября 2009 г.

Запись устанавливаемых зависимостей для пакета в Debian.

Часто приходится ставить софт "на посмотреть". Т.е. поставил, один-два раза запустил и удалил. Вроде бы ничего страшного - apt-get наш спаситель, но нередко бывает, что пакет при установке притягивает за собой толпы библиотек по зависимостям, и при удалении этого пакета все библиотеки остаются в системе. Часть из них, конечно, можно вычистить с помощью apt-get autoremove, но большая часть всё-таки остаётся. Я обычно в таких случаях записывал себе куда-нибудь список пакетов, устанавливаемых с нужным мне софтом и потом сносил его руками. Вот, решил этот процесс немного автоматизировать скриптом. Ничего особенного, просто небольшая экономия времени.

#!/bin/bash
#

INST_BASE=/var/cache/apt/Inst
INST_PROG=/usr/bin/apt-get

# Функция вывода ошибки в случае использования неправильных аргументов
f_argerror() {
    echo "depends_store.sh: Пропущен операнд."
    echo "Попробуйте \"depends_store.sh -h\" для получения более подробного описания."
}

# Функция записи данныхх о зависимостях с проверкой на наличие этих данных.
# Если данные имеются, вызывается функция их вывода.
f_install() {
  if [ -e ${INST_BASE}/${OPTARG} ]
  then
    echo "Данные о зависимостях для данного пакета уже присутсвуют."
    f_show
    exit 0
  fi
  ${INST_PROG} -s install ${OPTARG} | grep Inst | cut -d ' ' -f 2 > ${INST_BASE}/${OPTARG}
  echo `cat ${INST_BASE}/${OPTARG}`
}

# Функция удаления данных о зависимостях.
f_remove() {
  rm ${INST_BASE}/${OPTARG}
}

# Функция вывода данных о зависимостях.
f_show() {
  echo `cat ${INST_BASE}/${OPTARG}`
}

# Функция вывода списка пакетов, для которых есть записи о зависимостях.
f_list() {
  echo `ls ${INST_BASE}`
}

# Функция вывода справки.
f_help() {
echo "Использование: depends_store.sh КЛЮЧ [ПАКЕТ]"
echo "  -i ПАКЕТ      записать данные о зависимостях для пакета"
echo "  -r ПАКЕТ      удалить данные о зависимостях для пакета"
echo "  -s ПАКЕТ      показать данные о зависимостях для пакета"
echo "  -l              вывести список пакетов, для которых записаны данные о зависимостях"
echo "  -h              показать эту справку и выйти"
}

# Проверка на наличие аргументов коммандной строки.
if [ $# -eq "0" ]
then
  f_argerror
fi

# Проверка на наличие директории для хранения данных о пакетах и создание таковой в случае отсутсвия.
if [ ! -e ${INST_BASE} ]
then
  mkdir -p ${INST_BASE}
fi

# Перебор параметров командной строки.
getopts ":i:r:s:lh" Option
case $Option in
  i)
    f_install
  ;;
  r)
    f_remove
  ;;
  s)
    f_show
  ;;
  l)
    f_list
  ;;
  h)
    f_help
  ;;
  *)
    f_argerror
  ;;
esac

exit 0


Скрипт до безобразия простой, так что всё должно быть понятно из комментариев. :) Получился такой себе небольшой костыль над apt-get.
Работать с ним просто.
Нашли нужный пакетик, сказали на него ./depends_store.sh -i и всё запомнилось в базе. Поработали с пакетом, сделали apt-get purge `./depends_store.sh -s имя_пакета` && ./depends_store.sh -r имя_пакета и забыли о нём.

воскресенье, 27 сентября 2009 г.

На заметку. Грабли обновления курьера.

После обновления из портов courier-authdaemon во FreeBSD, всегда сбиваются права на файл
/var/run/authdaemond.
Если postfix настроен на авторизацию через курьеровский authdaemon, после обновления он ругнётся вот так:
postfix: warning: SASL authentication failure: cannot connect to Courier authdaemond: Permission denied
Надо Просто дать исполнение на этот файл.
chmod o+x /var/run/authdaemond
Третий раз уже на эти грабли наступаю.

четверг, 17 сентября 2009 г.

Мой vimrc

Вот, добрались руки упорядочить свой .vimrc
Пока что маленький и скромный, но со временем, думаю, функций добавится.

 1 " Подсветка синтаксиса
 2 syntax on
 3
 4 " Отключить режим совместимости с Vi
 5 set nocompatible
 6
 7 " Включить нормальную работу Backspace
 8 set backspace=indent,eol,start
 9
10 " История команд - 50
11 set history=50
12
13 " Вставка новой строки Enter'ом без перехода в режим вставки.
14
15 map <CR> o<Esc>
16
17 " Автоопределение файлов
18 filetype plugin on
19 filetype indent on
20
21 " Всегда показывать положение курсора
22 set ruler
23
24 " Показывать текущую команду
25 set showcmd
26
27 " Показывать режим работы
28 set showmode
29
30 " Поиск в реалтайме
31 set incsearch
32
33 " Хоткей Ctrl+n включает нумерацию строк, а Ctrl+b отключает.
34 map <C-n> <Esc>:set number<CR>
35 map <C-b> <Esc>:set nonumber<CR>
36
37 " Быстрое сохранение на <F2> во всех режимах
38 imap <F2> <Esc>:w<CR>
39 map <F2> <Esc>:w<CR>
40
41 " Выход без сохранения на <F10> во всех режимах
42 imap <F10> <Esc>:q!<CR>
44 map <F10> <Esc>:q!<CR>
45 " Вставка из буфера мыши
46 map <S-Insert> <Middlemouse>
47
48 " При вводе открывающей фигурной скобки автоматом вводится и закрывающая.
49
50 inoremap { {<CR>}<Esc>O
51
52 " При вводе закрывающей скобки подсвечивает открывающую
53 set showmatch
54
55 " Выключить любые звонки-мигалки
56 set novisualbell
57 set t_vb=
58 " Удаление от текущей позиции до конца строки по Ctrl+e
59 map <C-e> <Esc>d$

воскресенье, 12 июля 2009 г.

Lynksys, dd-wrt, vpn и локальные маршруты.

Есть некая локальная сеть. Довольно крупная, поэтому адреса локальных ресурсов занимают довольно большое количество подсетей. А выход в интернет осуществляется через vpn-подключение. И понадобился способ выпустить локальную сеть(офиса, или несколько домашних компов - неважно) в инет, при этом, чтобы локальные ресурсы были доступны напрямую, а не по vpn-каналу.
Конечно, это проще простого решается с помощью роутера с Linux, но каждому желающему такой роутер не поставишь. Вот и вспомнилась мне железка, с которой в своё время уже приходилось работать - Linksys WRT54-GL и свободная прошивка dd-wrt.

Что нам понадобится.
1. Сам Linksys WRT54-GL.
2. Список локальных сетей(в моём случае, его можно взять с сайтов местных провайдеров).
3. Прошивки dd-wrt последней версии(на момент написания этой заметки - 24) mini и standart. Всегда можно взять с официального сайта dd-wrt.
4. Немного времени.

Настройка:
1. Прошивка устройства.
В этот раз почему-то lynksys не захотел прошиваться сразу. Упорно был сбой при попытки запихнуть в него standart-версию. Решается просто. Сперва вшивается mini, а потом standart.
2. Настройка сети.
На вкладке Basic Setup для wan-интерфейса выставляем режим Static IP. Там прописывается ip-адрес, выдаваемый Вам провайдером и маску подсети. Шлюз не ставить!
Для Router IP, выставляем адрес и маску сети, по которому Linksys будет доступен в домашней локалке. И снова шлюз не ставить. Тут же надо указать dns-сервер, выданный провом.
Далее, по желанию. Я лично настроил раздачу адресов по локалке с помощью dhcp. Здесь всё.
Теперь решаем проблему, на которой затыкается большинство, судя по гуглу. Шлюз провайдера и vpn-сервер находятся в разных подсетях. Если указать default gateway, то vpn потом не будет работать. Если же его не указывать, то он и не подключиться. Но что мешает прописать отдельный маршрут к vpn-серверу через шлюз? Итак, идём на вкладку Setup -> Advanced Routing и добавляем нужный маршрут.
3. Настройка vpn.
Вкладка Services -> PPTP.
Ставим enable для PPTP Client, где и прописываем адрес vpn-сервера, логин и пароль. Если нужно, то опции шифрования.
4. Добавление маршрутов.
Последний штрих. Добавляем маршруты локальной сети.
Вкладка Administration -> Commands.
Все маршруты вписываем в поле commands в виде:
ip route add xx.xx.xx.xx/xx via yy.yy.yy.yy
Думаю, ясно, что это. Одно уточнение. Маска должна быть указана именно в виде битов, а не привычным для многих квартетным форматом - Linksys его не понимает.

Всё готово. Единственный ньюанс - внесение изменений в случае смены маршрутов в локалке. На роутере с linux у меня это решено простым скриптом, который по крону скачивает файл с маршрутами с сайта провайдера, и в соответсвии с ним вносит изменения в таблицу маршрутов. Вот, следующим шагом, думаю запихать этот скрипт в linksys(придётся немного переделать, потому как dd-wrt это всё-таки не полноценный linux).

понедельник, 1 июня 2009 г.

ssh-доступ в chroot для FreeBSD.

Есть у меня тут один web-сервер. Крутится на FreeBSD. И понадобилось организовать ssh-достп для программистов, чтобы они могли работать с разрабатываемыми сайтами напрямую. Но при этом было жёсткое условие - кроме своей рабочей директории программисты не должны видеть ничего, находящегося в системе.
Гугл штука хорошая, много рассказал, но там были всякие решения типа установки патченных версий sshd на другом порту или ограниченного доступа по sftp. Ограниченного доступа слишком мало, а патчить и плодить на сервере нестандартные вещи я не люблю.
В конце концов было выработано такое решение.
1. Создаём дерево chroot.
# mkdir /usr/chroot/
# mkdir /usr/chroot/bin
# mkdir /usr/chroot/dev
# mkdir /usr/chroot/etc
# mkdir /usr/chroot/home
# mkdir /usr/chroot/lib
# mkdir /usr/chroot/libexec
# mkdir /usr/chroot/sbin
# mkdir /usr/chroot/tmp
# mkdir /usr/chroot/usr
# mkdir /usr/chroot/var
# mkdir /usr/chroot/var/run
2. Копируем нужные команды и библиотеки.
У меня для /usr/chroot/bin - это: bash cat cp id ls mc mkdir mv rm scp sh svn
И для /usr/chroot/sbin - ldconfig
Список команд полностью зависит от ваших потребностей.
Теперь надо положить туда все библиотеки, необходимые для работы этих команд. Сразу же небольшое уточнение. Так как список команд и библиотек относительно небольшой, я не стал заморачиваться с фряшной системой расположения их по дереву(/usr/local/bin), а сложил всё в корне.
Для того, чтобы определить, какие библиотеки нам нужны, воспользуемся утилитой ldd. Для удобства, я это делал так:
# ldd /usr/local/bin/bash | grep -v \/usr\/local\/bin\/bash | cut -f 2 -d \> | cut -f 1 -d \(
/lib/libncurses.so.7
/usr/local/lib/libintl.so.8
/usr/local/lib/libiconv.so.3
/lib/libc.so.7
Это список необходимого для bash. Для остального по аналогии. Все эти библиотеки копируем в /usr/chroot/lib
Кроме этого, надо добавить симлинки типа libintl.so -> libintl.so.8
# ln -s libintl.so.8 linintl.so
И скопировать дополнительные *.a и *.la файлы. Подробнее надо смотреть для каждой отдельной библиотеки. В итоге мы должны получить что-то такое:
# ls /usr/chroot/lib/ | grep intl
libintl.a
libintl.la
libintl.so
libintl.so.8
Разумеется, так надо сделать для каждой необходимой библиотеки.
Ну и разумеется нужно скопировать основную фряшную утилиту, отвечающую за подгрузку библиотек:
# cp /libexec/ld-elf.so.1 /usr/chroot/libexec/ld-elf.so.1
3. Дополнительный компоненты для работы утилит.
Одних библиотек мало. У примеру, тому же mc надо ещё кучу всего. Тут, к сожалению, невозможно как-то заранее предсказать, что именно понадобится. В каждом отдельном случае надо читать документацию на программу и гуглить, если выдаёт ошибки. Для mc надо дополнительно скопировать полностью директории /usr/share/misc/ и /usr/local/share/mc/ в соответствующие места в chroot'е.
Так же для него понадобятся файлы termcap и shells в /usr/chroot/etc
В /usr/chroot/tmp надо будет создать директорию mc-root
4. Теперь подгатавливаем пользователя.
# adduser
Создаём обычного пользователя, только в качестве shell'a указываем ему путь к вот такому скрипту:
#!/usr/local/bin/bash
#
/usr/local/bin/sudo /usr/sbin/chroot /usr/chroot /bin/bash
Скрипту даём права на исполнение. Если не установлен пакет sudo, ставим и в /usr/local/etc/sudoers(можно воспользоваться командой visudo, если vim не страшен) добавляем строку имя_нашего_пользователя ALL=(ALL) NOPASSWD: /usr/sbin/chroot. Если править этот файл руками, надо не забыть после правки убрать права на запись, потому как sudo будет ругаться.
Командой passwd задаём для него пароль.
5. Монтируем устройства.
# mount -t devfs devfs /usr/chroot/dev
Готово.
Теперь логнинясь по ssh этим пользователем, человек попадает в chroot, из которого выхода нет.
Но этот голый chroot мне не нужен. Мне нужен доступ к определённым проектам. Я сделал так:
Отмонтировал devfs. Далее:
# cd /usr/chroot
# tar -cjvf /usr/backups/chroot.tar.bz2 ./
# cd /path/to/www_project
# tar -xjvf /usr/backups/chroot.tar.bz2
# mount -t devfs devfs /path/to/www_project/dev
И последнимс штрихом создание нового файла chroot.sh для конкретного пользователя с новым путём вместо /usr/chroot.
Теперь программер имеет доступ по ssh к сайту и не больше.
Решение пока сырое. Работаю над автоматизацией создания всего этого, плюс над созданием общего для всех chroot.sh, берущего конечную директорию из конфига(собственно, сделать это просто, но руки не доходят - много работы).