BSD

FreeBSD+ipfw+Squid+SquidGuard+… часть 6

Squid + SquidGuard +…

И вот наконец мы добрались до того, ради чего, собственно говоря, всё и затевалось.

Идея системы фильтрации и значительная часть ее реализации позаимствована из статьи Андрея Бешкова «Система фильтрации интернет траффика на основе squidGuard + Apache + Squid + Berkeley DB». К ней я и отсылаю интересующихся обоснованиями выбора именно такой системы. Здесь же рассмотрим только ее практическую реализацию.

Squid

Для начала устанавливаем из портов прокси сервер Squid. У меня использована стабильная версия 2.6 и именно ей посвящено дальнейшее описание. Версию 2.5 (также имеющуюся в портах) не рекомендую, т.к. там несколько более запутанная настройка. С новой 3.0 не экспериментировал, потому не могу гарантировать, что вся система будет работать без изменений в настройках. Итак…

# cd /usr/ports/www/squid26

# make install

По окончании установки редактируем конфигурационный файл:

# ee /usr/local/etc/squid/squid.conf

У меня он выглядит вот так (естественно, здесь отсутствует множество строк комментариев — этот файл, как это обычно и бывает в мире *nix, содержит внутри себя подробную документацию):

# Минимальные рекомендуемые права:
acl all src 0.0.0.0/0.0.0.0
acl manager proto cache_object
acl localhost src 127.0.0.1/255.255.255.255
acl to_localhost dst 127.0.0.0/8
acl SSL_ports port 443 563      # ssl
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443 563     # https
acl Safe_ports port 70          # gopher
acl Safe_ports port 210         # wais
acl Safe_ports port 1025-65535  # unregistered ports
acl Safe_ports port 280         # http-mgmt
acl Safe_ports port 488         # gss-http
acl Safe_ports port 591         # filemaker
acl Safe_ports port 777         # multiling http
acl CONNECT method CONNECT
# Разрешаем управление только с localhost
http_access allow manager localhost
http_access deny manager
# Запрещаем запросы к неизвестным портам
http_access deny !Safe_ports
# Запрещаем запрос CONNECT к чему-либо кроме портов SSL
http_access deny CONNECT !SSL_ports
# Открываем доступ к Squid всем, поскольку управлять
# доступом у нас уже будет SquidGuard. Так что двойная
# проверка ни к чему
http_access allow all
#
# Дальше идет очень важная строка. Именно тут отличие от
# предыдущих версий Squid. «прозрачный» прокси
# теперь включается гораздо проще — указанием
# параметра transparent
# Обрабатываем запросы на порт 3128 localhost
http_port 127.0.0.1:3128 transparent
#
# Что не должно кэшироваться. Просто рекомендованный
# разработчиками вариант:
hierarchy_stoplist cgi-bin ?
acl QUERY urlpath_regex cgi-bin \?
cache deny QUERY
# Размер оперативной памяти, отводимой под кэш
cache_mem 64 MB
# Каталог, где будет находиться кэш
# Число 4000 - размер кэша в мегабайтах, должен
# быть, как минимум, на 20% меньше свободного пространства
# в разделе диска
cache_dir ufs /usr/local/squid/cache 4000 16 256
# Количество старых лог-файлов, которые нужно хранить
# (по умолчанию 10, по-моему, даже 5 — много)
logfile_rotate 5
# То, что будет подставляться в качестве пароля при
# анонимном доступе к FTP-серверам
ftp_user vasja@pupkin.ru
# Если пользователь прервал загрузку, когда скачано
# не менее 70% файла, завершить его загрузку в кэш
quick_abort_pct 70
# Время жизни запросов, завершившихся ошибкой (напр., 404)
negative_ttl 1 minutes
# локальное имя или e-mail оператора, которому придет
# сообщение в случае аварии прокси (в нашем примере, admin)
cache_mgr admin
# Чтобы видеть сообщения об ошибках по-русски:
error_directory /usr/local/etc/squid/errors/Russian-koi8-r
# Не включать IP адрес клиента в заголовок запроса:
forwarded_for off
# Разрешаем управлять кэшем с помощью cachemgr.cgi
# В качестве пароля установим слово «secret»
cachemgr_passwd secret all
# Squid будет запускаться от имени пользователя squid
# и группы squid (это нам еще понадобится)
cache_effective_user squid
cache_effective_group squid
# Для поддержки клиентов, нестандартно закрывающих соединение
half_closed_clients on

Все остальные параметры (а их гораздо больше, чем тут перечислено) можно оставить так, как они назначены по умолчанию.

Далее мы должны создать каталоги для кэша и лог-файлов, а затем сделать так, чтобы их «владельцем» стал именно тот пользователь, от имени которого будет выполняться Squid (в нашем примере его зовут squid — см. конфигурационный файл выше):

# mkdir /usr/local/squid/cache

# mkdir /usr/local/squid/logs

# chown -R squid:squid /usr/local/squid/cache /usr/local/squid/logs

Впоследствие могут пригодится и некоторые другие ключи для запуска Squid

  • -d выводить на устройство stderr отладочную информацию
  • -f <имя_файла> запуск с другим файлом конфигурации
  • -h вывод справки
  • -k reconfigure отправка сигнала HUP (чтобы файл конфигурации был повторно прочитан; обычно используется после его изменений)
  • -k shutdown «вежливое» выключение
  • -k interrupt выключение, сразу разрывающее текущие соединения
  • -k kill принудительное прерывание работы
  • -v вывод информации о версии и ключах компиляции Squid
  • -X отладочный режим для разборки конфигурационного файла
  • -F ускоренное перестроение кэша после сбоя (но на время перестроения запросы не обслуживаются)

Далее необходимо создать в каталоге cache иерархию каталогов кэша (в соответствии с записью в конфигурационном файле там должно быть 16 каталогов, в каждом из которых — по 16 подкаталогов). Конечно, мы не будем делать это вручную. Воспользуемся самим Squid’ом:

# /usr/local/sbin/squid -z

Готово. Теперь можем запустить прокси-сервер в работу.

# /usr/local/sbin/squid -D

Ключ -D обозначает, что нам пока не нужно, чтобы Squid при запуске проверял работоспособность DNS-серверов (сейчас важно убедиться в работоспособности самого прокси).

Во время запуска на другой консоли (если мы работаем за компьютером непосредственно, консоли переключаются клавишами Alt+Fn, где n — номер консоли) или в другом терминальном окне (если работаем через SSH) наблюдаем за сообщениями, появляющимися в файле протокола:

# tail -f /var/log/messages

Вообще команда tail предназначена для вывода нескольких (по умолчанию, десяти) последних строк файла. Но добавление ключа -f <имя_файла> превращает ее в средство отслеживания добавляющихся в файл строк. Чтобы прервать ее работу в этом случае используют сочетание клавиш Ctrl+C.

Если всё сделано правильно, ошибок там не появится. А когда мы увидим что-то похожее на

Jul 9 11:22:49 sch415 squid[3792]: Squid Parent: child process 3794 started,

значит, Squid заработал. Можем попробовать позаходить на разные сайты с компьютеров локальной сети, а затем посмотреть файлы протоколов (они у нас, напомню, в /usr/local/squid/logs).

Apache

Вообще-то, Apache — очень совершенный http-сервер (на таких «живет» большая часть Интернет). Но у нас он будет подменять те сервера, которые мы, по той или иной причине, решили от пользователей закрыть. Как мы уже поступали со многими программами, установим сервер из портов:

# cd /usr/ports/www/apache13

# make install

Заметьте, мы устанавливаем версию 1.3, хотя в портах есть и 2.*. Эти версии существенно отличаются.

Запускаем Apache:

# /usr/local/apache/bin/apachectl start

Создаем каталог, в котором будут лежать файлы-подменки:

# mkdir /usr/local/apache/htdocs/replace

Помещаем туда (любым возможным способом: загрузкой с помощью links, копированием и т.п.) файлы 1x1.gif (он будет передаваться клиентам вместо баннеров), my.mp3 (маленький огрызок мелодии, который получит каждый желающий загрузить музыку), возможно, еще какие-либо картинки и т.п.

В каталог /usr/local/apache/cgi-bin помещаем специальный сценарий на perl — block.cgi. Он будет выводить сообщение при попытке посетить запрещенную страницу. Можно использовать либо оригинальный squidGuard.cgi.in из пакета SquidGuard, но лучше взять переведенный Андреем Бешковым. Чтобы скрипт смог работать, ему нужно выставить соответствующие права:

# chown nobody:wheel /usr/local/apache/cgi-bin/block.cgi

# chmod 500 /usr/local/apache/cgi-bin/block.cgi

Berkeley DB

Для работы SquidGuard необходима база данных, где будут храниться запреты. В этом качестве используется Berkeley DB. А она, в свою очередь, использует библиотеку libtool. На момент написания статьи ее актуальная версия — 1.5.26. Установка обычным способом из портов у меня не сработала (да, ошибки встречаются везде), потому пришлось загрузить архив с сайта (нужно воспользоваться ссылкой «Download this directory in tarball»), распаковать его и полностью выполнить процедуру сборки и инсталляции.

# tar zxvf libtool15.tar.gz

# cd libtool15

# make

(после этой команды будет выполнена загрузка исходников, которая может занять достаточное время при медленном канале, а затем компиляция)

# make install

При выполнении дух последних команд смотрим внимательно на появляющиеся сообщения, если что-то происходит не так, наиболее важная информация для понимания причин неприятности будет в последних строчках.

После установки libtool займемся Berkeley DB. Тут процесс будет заметно более сложным. Для начала нам нужно загрузить исходный код и два патча. Внимание! Нужна версия 3.2.9. Я не перепроверял, но по данным Андрея Бешкова только она может быть успешно собрана под FreeBSD. Распаковываем архив исходников, копируем в него оба патча и применяем их по очереди:

# tar zxvf db-3.2.9.tar.gz

# cp patch.3.2.9.1 patch.3.2.9.2 ./db-3.2.9

# cd db-3.2.9

# patch -p0 < patch.3.2.9.1

# patch -p0 < patch.3.2.9.2

А дальше — компилируем и устанавливаем:

# cd build_unix

# ../dist/configure

# make

# make install

SquidGuard

Ну, вот дело дошло и до последнего компонента нашей системы — редиректора SquidGuard. Его мы, как и предыдущие программы, соберем из исходников. Начнем с их загрузки с www.squidguard.org. Затем распакуем, скомпилируем и установим:

# tar zxvf squidGuard-1.3.tar.gz

# cd squidGuard-1.3

# ./configure --prefix=/usr/local/squidGuard \

--with-db=/usr/local/BerkeleyDB.3.2 \

—with-sg-config=/usr/local/squidGuard/squidGuard.conf \

—with-sg-logdir=/usr/local/squidGuard/log \

--with-sg-dbhome=/usr/local/squidGuard/db

# make

# make test

# make install

Обратите внимание на «страшную» команду configure (эти несколько строк именно одна команда). В ней мы указали: 1) куда будет установлен SquidGuard; 2) где находится библиотека BercleyDB; 3) где будет лежать файл конфигурации программы; 4) куда будут записываться файлы протоколов и 5) где будет база данных блокируемых сайтов. Естественно, ошибиться при вводе этой команды крайне нежелательно.

Создаем каталог для протоколов:

# mkdir /usr/local/squidGuard/log

Теперь нам нужен список «нехороших» сайтов. В сети есть несколько источников таких списков. Я воспользовался помощью наших американских коллег. Загружаем список. Распакуем его и перенесем в каталог, заданный при конфигурации:

# tar zxvf blacklists.tgz -C /usr/local/squidGuard

# mv /usr/local/squidGuard/blacklists /usr/local/squidGuard/db

В появившихся подкаталогах будут находиться файлы domains (домены, блокируемые целиком), urls (если нужно блокировать страницу, а не весь домен) и expression (регулярные выражения, определяющие, какие подстроки запрещены в url).

Категории блокируемых сайтов
База Комментарии
ads реклама
adult сайты для взрослых
aggressive агрессия
audio-video музыка и видео
forums форумы
drugs наркотики
gambling азартные игры
hacking хакерство
local-block сайты заблокированные местным админом
local-ok сайты разрешенные местным админом
mail бесплатные почтовые сервера
porn порнография
proxy общедоступные прокси сервера
publicite опять реклама
redirector анонимные прокси сервера
violence насилие
warez пиратское програмное обеспечение

К этой базе добавим еще базу баннеров (banners).

Теперь нам необходимо настроить SquidGuard. Создаем файл squidGuard.conf

# ee /usr/local/squidGuard/squidGuard.conf

Выглядеть он может примерно так:

# куда записывать протоколы:
logdir /usr/local/squidGuard/log
# где находится база данных:
dbhome /usr/local/squidGuard/db
#
# Дальше описываем диапазоны адресов для разных групп пользователей
# === ИТ инфраструктура
src it-computers {
ip 10.0.1.1, 10.0.1.100, 10.0.1.210
}
# === Компьютерные классы
src nachalka {
ip 10.0.1.50-10.0.1.56
}
src r33 {
ip 10.0.1.211-10.0.1.222
}
src books {
ip 10.0.1.101-10.0.1.113
}
# === Библиотека
src library {
ip 10.0.1.238
}
# === Работники школы
src staff {
10.0.1.231-10.0.1.254
}
# =============

# При попытке загрузить запрещенные типы файлов подменяем их:
rewrite media {
s@.*\.mp3$@http://10.0.1.1/replace/my.mp3@r
s@.*\.swf$@http://10.0.1.1/replace/noflash.jpg@r
s@.*\.flv$@http://10.0.1.1/replace/noflash.jpg@r
s@.*\.wmv$@http://10.0.1.1/replace/stop300.gif@r
s@.*\.mov$@http://10.0.1.1/replace/stop300.gif@r
s@.*\.exe$@http://10.0.1.1/replace/stop300.gif@r
log rewr
}

# Теперь отметим, какие базы и как будут использоваться
# Порнографию просто отрубаем с записью в протокол
dest porn {
domainlist porn/domains
urllist porn/urls
log porn
}
# рекламные картинки и баннеры заменяем на 1-пиксельный GIF
dest ads {
domainlist ads/domains
urllist ads/urls
log ads
redirect http://10.0.1.1/replace/1x1.gif
}
dest banners {
domainlist banners/domains
urllist banners/urls
# expressionlist banners/expressions
log banners
redirect http://10.0.1.1/replace/1x1.gif
}
# Сайты и страницы, не требующие проверки
dest local-ok {
domainlist local-ok/domains
urllist local-ok/urls
}
# Сайты, добавленные к базе (из Америки видно не всё ;-))
dest local-block {
domainlist local-block/domains
urllist local-block/urls
log local-block
redirect http://10.0.1.1/cgi-bin/block.cgi?clientaddr=%a&clientname=%n
&clientident=%i&clientgroup=%s&targetgroup=%t&url=%u
}

# Теперь распределяем, каким группам пользователей что можно
acl {
	# пропускать все, кроме рекламы:
	it-computers {
	pass local-ok !banners !ads all
	}
	# в компьютерных классах ограничений больше всего:
	nachalka {
	pass local-ok !porn !banners !ads !local-block all
	rewrite media
	}
	r33 {
	pass local-ok !porn !banners !ads !local-block all
	rewrite media
	}
	# а здесь разрешим загружать музыку и т.п.
	books {
	pass local-ok !porn !banners !ads !local-block all
	}
	library {
	pass local-ok !porn !banners !ads !local-block all
	}
	staff {
	pass local-ok !porn !banners !ads !local-block all
	}
	# с компьютеров, не входящих в группы, доступ к Интернет закрыт:
	default {
	pass none
	redirect http://10.0.1.1/cgi-bin/block.cgi?clientaddr=%a
	&clientname=%n&clientident=%i&clientgroup=%s&targetgroup=%t&url=%u
	log default
	}
}
# === end of acl

Установим права на служебные файлы и каталоги (сделаем их владельцем пользователя, от имени которого будет работать SquidGuard):

# chown -R nobody /usr/local/squidGuard/log /usr/local/squidGuard/db

# chown nobody /usr/local/squidGuard/squidGuard.conf

Чтобы SquidGuard не строил при каждом запуске базы данных в оперативной памяти, напишем сценарий, который построит их (сохранив на диске) и перезапустит Squid (и с ним SquidGuard):

# ee /usr/local/squidGuard/bin/rebuild_base.sh

#!/bin/sh
/usr/local/squidGuard/bin/squidGuard -C all
chown -R squid /usr/local/squidGuard/db
/usr/bin/killall -HUP squid

Установим необходимые права (этот сценарий должен иметь право запускать только root, а остальным с ним вообще ничего делать нельзя), а затем запустим его:

# chmod 100 /usr/local/squidGuard/bin/rebuild_base.sh

# /usr/local/squidGuard/bin/rebuild_base.sh

Теперь ждем, когда задача будет завершена. Процесс не слишком быстрый. Затем протестируем работу SquidGuard. Воспользуемся написанной опять же Андреем Бешковым маленькой тестовой программкой на Перле. Загружаем архив, распаковываем его и помещаем полученный файл test.pl в каталог /usr/local/squidGuard/bin. Устанавливаем ему разрешение на исполнение, запускаем и вводим тестируемый IP-адрес. В файле result.txt смотрим результат. (Там, где результат — пустая строка, сайт будет доступен, во всех остальных случаях показана строка, на которую произойдет перенаправление Squid’а) Набор сайтов можно поменять, отредактировав сценарий. Если результаты теста нас удовлетворили, подключим SquidGuard к Squid. Для этого в файл /usr/local/etc/squid/squid.conf добавим следующие строки:

# если не отвечает ни один экземпляр SquidGuard, работать напрямую
redirector_bypass on
# где находится SquidGuard
redirect_program /usr/local/squidGuard/bin/squidGuard
# сколько экземпляров SquidGuard запускать
redirect_children 10
#

Перезапускаем Squid (а редиректоры он уже [пере]запустит сам):

# killall -HUP squid

Если после этого в конце файла протокола /usr/local/squidGuard/log/squidGuard.log появились строки, подобные:

2008-07-10 14:57:54 [1285] squidGuard 1.2.0 started (1215687474.577)

2008-07-10 14:57:54 [1285] squidGuard ready for requests (1215687474.645)

…значит все запустилось нормально. Теперь сделаем, чтобы наша система запускалась автоматически при загрузке компьютера. Для этого внесем два сценария в «стартовый каталог» FreeBSD rc.d:

# ee /usr/local/etc/rc.d/apache.sh

#!/bin/sh
/usr/local/apache/bin/apachectl start

# ee /usr/local/etc/rc.d/squid.sh

#!/bin/sh
/usr/local/sbin/squid -D

# chmod 100 /usr/local/etc/rc.d/apache.sh /usr/local/etc/rc.d/squid.sh

Перезагружаем компьютер, убеждаемся, что все нормально работает.

Для полного счастья админа школьной сети недостает только автоматического обновления баз блокируемых сайтов. Что делать?— естественно, писать сценарий. Базу надо скачать, распаковать, перенести в каталог баз данных SquidGuard, после чего запустить уже имеющийся сценарий перегенерации БД:

# ee /usr/local/squidGuard/bin/update_blacklist.sh

#!/bin/sh
/usr/local/bin/wget -q --cache=off \
'http://squidguard.mesd.k12.or.us/blacklists.tgz' \
-O /usr/local/squidGuard/update/blacklist.tgz
tar zxvf /usr/local/squidGuard/update/blacklist.tgz -C \
/usr/local/squidGuard/update/
cp -R -f /usr/local/squidGuard/update/blacklists/* /usr/local/squidGuard/db
rm -R /usr/local/squidGuard/update/blacklists
/usr/local/squidGuard/rebuid_base.sh

Устанавливаем права:

# chmod 100 /usr/local/squidGuard/bin/update_blacklist.sh

Создаем временный каталог для распаковки:

# mkdir /usr/local/squidGuard/update

И настраиваем планировщик cron на периодическое выполнение сценария обновления:

# crontab -e -u root

Запускаем редактирование (-e) таблицы периодических заданий пользователя (-u) root. Для просмотра таблицы нужно было бы использовать ключ -l.

Запустится указанный в настройках ОС текстовый редактор (по умолчанию это vi). С его помощью дополним файл примерно такой строкой:

1  15  *  *  5  /usr/local/squidGuard/bin/update_blacklist.sh

Она означает, что файл update_blacklist.sh должен запускаться каждую пятницу (5 день недели) в 15 часов 1 минуту. Правильнее было бы назначать обновление на ночное время (например, на 2 часа и сколько-то-там минут), но мы по правилам не можем оставлять компьютеры включенными на ночь.

vi — редактор с непривычным для людей не из мира *nix интерфейсом. Для выхода из него нужно сделать следующее:

— нажимаем Esc — редактор переходит в командный режим

— нажимаем : (двоеточие, оно появится в нижней строке экрана) — редактор переходит в расширенный режим

— набираем wq<Enter> — файл сохраняется и завершается работа с редактором.

Вот, собственно говоря, и всё. Два учебных года — полёт нормальный. Помимо добавления нескольких адресов в список запрета, никаких дополнительных телодвижений. Утром щелкнул выключателем, вечером — shutdown -h now. Бывало, в нарушение правил, машинка (P-II/333MHz/256M) работала по несколько суток не выключаясь.


PS Заметка была написана почти два года назад. С тех пор система умудрилась проработать полтора года практически без участия человека (и почти без выключения). Единственная поломка — выход из строя… одной из сетевых карт.

Опубликовано Михаил К в FreeBSD

FreeBSD+ipfw+Squid+SquidGuard+… часть 5

Дополнительные программы

Следующий этап нашей работы — установка вспомогательных программ, без которых можно бы и обойтись… но не стоит 😉 Перво-наперво обеспечим себя средствами для загрузки и установки программ.

Программы на компьютере с FreeBSD появляются двумя способами. Один из них — ручная сборка из исходников («ручная», это, пожалуй, громко сказано — чаще всего требуется набрать три-четыре команды). Другой — установка из портов (гигантской коллекции сценариев, в которых определено, что именно нужно загрузить, как установить и настроить). При установке ОС мы выбрали, в числе прочего, и коллекцию портов. Так что она у нас есть. Однако, прежде чем пользоваться, не мешает ее обновить… А средство обновления будет установлено из той самой коллекции, которая у нас есть. Переходим в каталог нужного нам порта (не забывая предварительно перейти под рута):

# cd /usr/ports/net/cvsup-without-gui

Ах, да. Забыл сказать: программу, которую мы сейчас будем собирать, зовут CVSup, и нужна нам ее версия без графического интерфейса (without GUI). Далее запускаем сборку:

# make install

Теперь компьютер автоматически загрузит требуемые компоненты, скомпилирует их и установит в нужное место дерева каталогов. Мы же можем немного отдохнуть.

Чтобы указать CVSup, откуда брать данные обновленных портов и все ли оттуда нам нужно, напишем конфигурационный файл:

# ee /etc/cvsupfile

Выглядеть он будет примерно вот так:

*default host=cvsup.ru.freebsd.org
*default base=/usr
*default prefix=/usr
*default release=cvs
*default tag=.
*default delete=use-rel-suffix
# можно было бы обновить все порты разом:
# ports-all
# но мы обновляем только необходимые
# некоторые строчки я закомментировал,
# поскольку сейчас они мне не нужны
#ports-archivers
#ports-converters
#ports-databases
ports-devel
#ports-dns
#ports-editors
#ports-graphics
ports-ftp
ports-lang
#ports-mail
#ports-net
#ports-net-mgmt
ports-russian
#ports-security
#ports-shells
#ports-sysutils
ports-www

Теперь запустим обновление портов:

# /usr/local/bin/cvsup -g -L 2 /etc/cvsupfile

Использованные ключи команды cvsup, во-первых, отключают попытки использовать графический интерфейс (-g), а во-вторых, устанавливают подробный вывод информации о каждом обновленном файле (-L 2). Если поставить цифру 1 (или вообще убрать ключ L), обновленные файлы будут просто перечисляться. Ноль вообще отключит всякий вывод, кроме информации об ошибках. На будущее, вполне возможно, Вы предпочтете именно этот, последний, вариант.

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

Во-первых, совершенно необходимым для нас будет wget. Это утилита для загрузки файлов из Интернет (а нам нужно будет, помимо всяких мелочей, регулярно обновлять базу «нехороших» сайтов). Действуем практически так же, как и с CVSup:

# cd /usr/ports/ftp/wget

# make install

Далее тем же самым способом ставим браузер links:

# cd /usr/ports/www/links1

# make install

Поначалу гулять по Сети в текстовом режиме несколько непривычно, тем не менее, это совсем несложно. На красоты дизайна, конечно же, полюбоваться не удастся, но получать информацию можно не хуже, чем с IE или FF.

Несколько сложней будет установить файловый менеджер Midnight Commander (по своему назначению и интерфейсу он очень похож на хорошо известный Norton Commander и его родственников). Из дерева портов мы сможем установить только необходимую для его работы библиотеку glib:

# cd /usr/ports/devel/glib12

# make install

А вот саму программу придется собирать из исходников. Для выполнения большей части действий права суперпользователя нам сейчас не нужны, так что вернемся к своему обычному статусу (помните команду exit?). В своем домашнем каталоге создадим подкаталог, куда будем скачивать исходники программ, и перейдем в него:

$ cd ~

$ mkdir install

$ cd install

Запускаем отсюда links и заходим на сайт http://www.ibiblio.org/mc/

$ links http://www.ibiblio.org/mc/

Скачиваем исходники (source) последней стабильной версии (у меня это была версия 4.6.1). Затем выходим из links, разворачиваем загруженный архив, переходим в получившийся каталог и настраиваем, какой вариант программы нужно собрать.

$ tar xzfv mc-4.6.1.tar.gz

$ cd mc-4.6.1

$ ./configure --with-edit --without-x --enable-charset=yes

Обратите внимание на эту характерную особенность unix-подобных систем: мы можем не только выбрать набор программ по своему вкусу, но и многие из этих программ оптимизировать под свои нужды. Мнения на этот счет есть прямо противоположные. Кто-то предпочитает строить рабочий процесс из большого числа программ, каждая из которых выполняет одну задачу, зато максимально эффективно. Кого-то такой подход приводит в ужас: пусть будет несколькосотмегабайтный монстр, 99% функций которого в повседневной работе совершенно не нужны, но если вдруг что-то понадобится…

Теперь выполняем сборку и, если все завершилось нормально (т.е. без сообщений об ошибках — строк со словами ERROR), вновь становимся суперпользователем и устанавливаем готовую программу.

$ make

$ su

# make install

Теперь можно включить наш файловый менеджер… Стоп! По умолчанию он запускается в черно-белом режиме, однако у Вас, я думаю, монитор — цветной, так что отказываться от цвета было бы глупо. Чтобы Midnight Commander работал в полноцветном режиме, его нужно запускать с ключом -c… или создать новую команду, написав файл сценария. Это совсем просто:

# ee /usr/local/bin/midc

Файл будет состоять из единственной строки:

mc -c

А чтобы компьютер понял, что это не какие-то там данные, а программа, которую нужно исполнять, мы просто соответствующим образом выставляем права доступа:

С командой chmod (Change Mode = сменить режим) рекомендую очень хорошо разобраться. Она бывает нужна регулярно. Пока поясню, что число 755 обозначает, что владелец файла (в данном случае, root) может делать с файлом всё, что угодно (первая цифра — 7); члены административной группы wheel (вторая цифра) и все остальные (третья цифра) — просматривать файл и запускать его (но не изменять).

# chmod 755 /usr/local/bin/midc

Пока что для запуска нашего командного файла придется указывать полный путь:

$ /usr/local/bin/midc

Но уже после следующего входа в систему эта команда будет действовать абсолютно также, как и все существовавшие ранее, т.е. запускать Midnight Commander мы будем просто набирая

$ midc

Опубликовано Михаил К в FreeBSD, 0 комментариев

FreeBSD+ipfw+Squid+SquidGuard+… часть 4

Настройка основных сервисов

После загрузки войдем в систему под именем суперпользователя root. Выполним некоторые настройки, после которых наш сервер уже будет пригоден к использованию (хотя намеченные задачи выполнять еще не будет). Во-первых, добьемся возможности вводить с консоли русские буквы. Для этого введем команду:

# pw usermod root -L russian

Естественно, чтобы увидеть результат изменения параметров входа пользователя в систему, нужно из нее выйти:

# logout

…и вновь войдем в нее под именем root.

Готово. Теперь мы можем писать по-русски. И сразу небольшой сюрприз для тех, кто привык к графическим интерфейсам ОС. Переключение на русскую раскладку клавиатуры происходит не по Alt+Shift, как в Windows, и не по Command+Space, как в Mac OS X, а с помощью Caps Lock. Все равно эта клавиша по назначению используется весьма нечасто (а заодно появляется индикатор включенной раскладки).

Утилита pw предназначена для управления пользователями и группами. В данном случае мы меняем у пользователя (user-mod[ify]) с именем root класс входа (L[ogin class]) на russian, указывая таким образом, что суперпользователь у нас предпочитает работать с русским языком. Для любопытныхзнательных подскажу, что классы описываются в файле /etc/login.conf.

Еще мы можем отключить вывод сообщений на консоль root’а. Когда система будет работать «на автопилоте» без монитора, они станут совершенно бесполезными. Если что понадобится — можно прочесть в соответствующем логе (log-file — файл протокола). Естественно, отключать или не отключать и отключать сразу сейчас или по окончании процесса настройки — дело ваших личных предпочтений.

# ee /etc/syslog.conf

В этом файле нужно закомментировать (т.е. поставить в самом ее начале знак #) всего одну строку:

*.err;kern.warning;auth.notice;mail.crit                /dev/console

Кстати, обратите внимание: подсказки и прочие элементы интерфейса редактора ee теперь написаны по-русски.

Следующий наш шаг — перенос временного каталога /tmp. Изначально он находится в корневой файловой системе, однако под эту систему мы отвели довольно маленький раздел диска, где при определенном стечении обстоятельств места может и не хватить. Поэтому создадим каталог /var/tmp (помните? /var у нас сделан отдельным разделом). Укажем на него, создав в корневой системе символическую ссылку вместо предварительно удаленного каталога:

Использованные ключи команды удаления rm обозначают, что мы хотим удалить каталог и все его содержимое (файлы и каталоги) рекурсивно. Вообще к команде удаления в Unix-подобных системах нужно подходить с большой внимательностью. Если не поставить ключ -i, она всю свою работу сделает абсолютно «молча» (никаких Вам «Вы действительно хотите отправить этот файл в Корзину? Вы действительно хотите почистить Корзину?»; сразу — и навсегда).

# rm -R /tmp

# ln -s /var/tmp /tmp

SSH

Обычно компьютер, выполняющий ответственные функции, прячут подальше от «шаловливых ручек», а зачастую используют без монитора и клавиатуры. Однако при этом тут же возникает проблема, как им управлять. Что ж, обеспечим удаленный доступ с помощью SSH (Secure SHell — протокол, специально предназначенный для безопасного — т.е. с использованием шифрования передающихся данных — управления удаленным компьютером). Клиенты SSH стандартно входят во все Unix/Linux (включая Mac OS X), есть несколько таких программ и для Windows. На сервере же все необходимые функции обеспечивает демон sshd.

Демон (англ. daemon) — в системах Unix (Linux) — программа, работающая в фоновом режиме без прямого взаимодействия с пользователем.

Откроем конфигурационный файл sshd, используя уже знакомый редактор ee:

# ee /etc/ssh/sshd_config

Раскомментируем строки (т.е. удалим значок # в начале каждой из них):

Port 22
Protocol 2

Чтобы была возможность подключаться, используя аутентификацию по паролю, изменяем строку

# PasswordAuthentication no

на

PasswordAuthentication yes

Выходим из редактора с сохранением изменений и перезапускаем sshd:

# killall -HUP sshd


До сих пор мы работали от имени суперпользователя, а это, вообще говоря, нехорошо. Подключиться же к удаленному компьютеру, используя учетную запись root, вообще не удастся. Поэтому сейчас необходимо создать пользователя административной группы (она называется wheel). Такой пользователь может с помощью команды su временно «становится рутом». Допустим, его имя — admin. В этом случае команда будет выглядеть так:

# pw useradd admin -c "Admin" -L russian -g wheel -d /home/admin -s /bin/csh

Здесь: «Admin» — «полное имя» пользователя; wheel — группа; /home/admin — домашний каталог; /bin/csh — командный процессор (мне нравится csh, но можно использовать и другой).

Теперь зададим пароль для вновь созданного пользователя (как обычно, его придется набрать дважды):

# passwd admin

Наконец, создадим домашний каталог:

# mkdir -p /usr/home/admin

# ln -s /usr/home /home

# chown -R admin /home/admin


NTP

Запустим некоторые полезные для локальной сети сервисы. Во-первых, сделаем так, чтобы только наш сервер-шлюз синхронизировал часы по внешнему серверу NTP (Network Time Protocol), а все машины локалки обращались бы уже к нему. Для этого мы настроим демон ntpd, создав файл /etc/ntp.conf следующего вида:

server europe.pool.ntp.org
server europe.pool.ntp.org
server europe.pool.ntp.org
server europe.pool.ntp.org
server europe.pool.ntp.org
driftfile /var/db/ntp.drift
restrict 10.0.1.0 mask 255.255.255.0 nomodify notrap

Естественно, в параметре restrict указываем адрес/маску локальной сети (мы же не собираемся обслуживать что-то вне ее!).

Повторенная несколько раз строка «server europe.pool.ntp.org»— не ошибка, а указание на пул серверов времени (т.е. нескольких «параллельно используемых» серверов).

Параметр driftfile указывает файл, где хранится смещение частоты системных часов. Знание его позволяет компьютеру поддерживать достаточно высокую точность, даже если он оказался временно отключенным от Интернет. Этот файл необходимо создать:

# touch /var/db/ntp.drift

Теперь сделаем так, чтобы программы для синхронизации часов запускались при загрузке компьютера. Для этого добавим к файлу /etc/rc.conf следующие строки:

# ----------- Network Time Protocol --------
ntpdate_enable="YES"
ntpdate_flags="-b europe.pool.ntp.org europe.pool.ntp.org europe.pool.ntp.org"
ntpd_enable="YES"
ntpd_flags="-c /etc/ntp.conf -l /var/log/ntpd.log -p /var/run/ntpd.pid"

DNS

Следующая служба, которую полезно иметь внутри локальной сети — DNS. Она будет работать в режиме кэширующего DNS-сервера, т.е. однажды запрошенное доменное имя в дальнейшем будет преобразовываться в IP-адрес уже без обращения к внешним серверам. Нам необходимо сделать две вещи. Во-первых, создать файл локальной зоны. В этом поможет уже готовый сценарий командного процессора:

# sh /var/named/etc/namedb/make-localhost

Во-вторых, настроим собственно DNS-сервер. Для этого служит файл /var/named/etc/namedb/named.conf, он должен выглядеть примерно так:

options {
        directory       "/etc/namedb";
        pid-file        "/var/run/named/pid";
        dump-file       "/var/dump/named_dump.db";
        statistics-file "/var/stats/named.stats";
        forward first;
        forwarders {
                212.45.0.3; // DNS-сервер провайдера
                212.45.2.5; // DNS-сервер провайдера
                208.67.222.222; // DNS-сервер OpenDNS (на всякий случай)
                208.67.220.220; // DNS-сервер OpenDNS (на всякий случай)
        };
        query-source address * port 53; // поскольку у нас есть proxy
        version "DNS";
};
zone "." {
        type hint;
        file "named.root";
};

zone "0.0.127.IN-ADDR.ARPA" {
        type master;
        file "master/localhost.rev";
};
// RFC 3152
zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA" 
{
        type master;
        file "master/localhost-v6.rev";
};

Пересборка ядра. Firewall. NAT

Следующий важный этап подготовки нашей системы — включение firewall и NAT. Для этого придется пересобрать ядро ОС. Звучит страшно, но, на самом деле, в мире Unix-подобных ОС это совершенно обычная операция. При установке мы получаем некое универсальное ядро, способное загрузиться практически на любой возможной конфигурации. Однако, с одной стороны, там много избыточного, а с другой стороны, некоторые функций, необходимые в конкретной ситуации, отключены.

Чтобы настроить систему под наши, вполне определенные, задачи, следует «построить» новое ядро, которое и будет в дальнейшем использоваться вместо GENERIC. Во-первых, сделаем копию конфигурационного файла GENERIC и назовем его, к примеру, MyKern:

# cd /usr/src/sys/i386/conf

# cp GENERIC MyKern

В файл MyKern вносим необходимые изменения. Во-первых, изменяем строку

ident	GENERIC

на

ident	MyKern

Во-вторых, добавим строку

maxusers	64

(это условное значение, по которому рассчитываются внутренние таблицы; вообще говоря, можно использовать значение «0», положившись на автоматически рассчитываемые параметры).

Кроме того, нам потребуется указать следующие опции (из-за которых все и затевалось):

options         IPFIREWALL
options         IPFIREWALL_VERBOSE
options         IPFIREWALL_VERBOSE_LIMIT=100
options         IPFIREWALL_FORWARD
options         IPDIVERT

При желании можно попробовать несколько оптимизировать ядро под свое «железо», закомментировав часть строк файла (что именно, на мой взляд, там достаточно понятно, а если непонятно — имеется документация).

Теперь компилируем новое ядро:

# config MyKern

# cd ../compile/MyKern

# make depend

Теперь можно выпить кофе… или сходить пообедать 😉 Процесс достаточно долгий. По окончании, если не было сообщений об ошибках (а их, если все вписано правильно, и не должно быть), даем следующую команду:

# make

Можно снова заняться каким-нибудь другим делом — этот этап тоже долгий. Но зато, когда он закончится (без ошибок — их опять-таки появиться не должно, но… всякое бывает), можно будет устанавливать новое ядро:

# make install

Ну, вот. Поддержка файрвола в ядре есть. А для его настройки используется файл /etc/rc.firewall. Создадим файл с нужными нам правилами, предварительно переименовав имеющийся (чтобы сохранить его на всякий случай):

# mv /etc/rc.firewall /etc/rc.firewall.default

# ee /etc/rc.firewall

#! /bin/sh
################### rc.firewall ###################
fwcmd="/sbin/ipfw"
uports="1025-65535"
services="smtp,pop3,imap,http,https,domain,ssh,ftp"
echo -n "Starting firewall..."
${fwcmd} -f flush
####################################################
# внешний сетевой интерфейс
oif="de0"
# нач. адрес - 192.168.4.129, маска - 255.255.255.192
onet="192.168.4.128/26"
# IP-адрес внешнего интерфейса
oip="192.168.4.131"
# внутренний сетевой интерфейс
iif="xl0"
# локальная сеть: 10.0.1.1-10.0.1.254, маска - 255.255.255.0
inet="10.0.1.0/24"
# IP-адрес внутреннего интерфейса
iip="10.0.1.1"
####################################################
${fwcmd} add pass all from any to any via lo0
${fwcmd} add deny all from any to 127.0.0.0/8
${fwcmd} add deny ip from 127.0.0.0/8 to any in via ${oif}
#
# === Stop private networks from outside ===
#
# У нас несколько необычная конфигурация: «внешняя»
# сеть является приватной сетью класса C.  
# В нормальной ситуации следующие две строки нужно
# раскомментировать:
# ${fwcmd} add deny ip from 192.168.0.0/16 to any in via ${oif}
# ${fwcmd} add deny all from any to 192.168.0.0/16 out via ${oif}
#
${fwcmd} add deny ip from 172.16.0.0/12 to any in via ${oif}
${fwcmd} add deny all from any to 172.16.0.0/12 out via ${oif}
${fwcmd} add deny ip from 10.0.0.0/8 to any in via ${oif}
${fwcmd} add deny all from any to 10.0.0.0/8 out via ${oif}
#
#
# Следующие строки нам потребуются после установки Squid,
# поэтому пока их закомментируем:
# ============== Transparent Proxy ==================
# ${fwcmd} add allow all from ${inet} to 10.0.1.1 80 in via ${iif}
# ${fwcmd} add fwd 127.0.0.1,3128 tcp from ${inet} to any 80,8080 in via ${iif}
# ============ End  Transparent Proxy ===============
#
#
# 
# === filter only external traffic ===
${fwcmd} add allow all from ${inet} to any in via ${iif}
${fwcmd} add allow all from any to ${inet} out via ${iif}
# 
# === NAT ===
${fwcmd} add divert natd all from ${inet} to any out via ${oif}
${fwcmd} add divert natd all from any to ${oip} in via ${oif}
#

#
###
${fwcmd} add pass tcp from any to any established
${fwcmd} add pass ip from ${oip} to any out xmit ${oif}
#
# --- DNS ---
${fwcmd} add pass udp from ${oip} ${uports} to any domain out xmit ${oif}
${fwcmd} add pass udp from any domain to ${oip} ${uports} in recv ${oif}
${fwcmd} add pass udp from any domain to ${inet} ${uports} in recv ${oif}
${fwcmd} add pass udp from ${oip} to any 53 keep-state
${fwcmd} add pass udp from any to ${oip} 53 keep-state
${fwcmd} add pass udp from ${iip} to ${inet}:${imask} 53 keep-state
${fwcmd} add pass udp from ${inet}:${imask} to ${iip} 53 keep-state
${fwcmd} add pass udp from ${oip} to any 123 keep-state
${fwcmd} add pass udp from any 123 to ${oip} keep-state
${fwcmd} add pass udp from ${iip} 123 to ${inet}:${imask} keep-state
${fwcmd} add pass udp from ${inet}:${imask} to ${iip} 123 keep-state
#
# --- ICMP (ping etc) ---
#${fwcmd} add deny icmp from any to any frag
${fwcmd} add allow icmp from any to any 
#
#${fwcmd} add allow icmp from any to me icmptypes 0,3,4,11,12 in
#${fwcmd} add allow icmp from any to ${inet} icmptypes 0,3,4,11,12 in recv ${oif
}
#${fwcmd} add allow icmp from me to any icmptypes 3,8,12 out
###
${fwcmd} add pass tcp from ${oip} ${uports} to any ${services} out xmit ${oif} 
###
${fwcmd} add deny log logamount 700 tcp from any to ${oip} in recv ${oif} setup
${fwcmd} add deny all  from any to any 
###
echo "Done!"
#
############ END #############

Осталось указать, что при запуске системы следует включать firewall и NAT. Как вы уже, вероятно, поняли, для этого нужно дописать соответствующие строки в файл /etc/rc.conf:

firewall_enable="YES"              # при необходимости/желании можно «открыть»
# firewall_type="OPEN"             # firewall, раскомментировав эту строчку
firewall_script="/etc/rc.firewall" # и закомментировав эту
natd_enable="YES"
natd_interface="de0"

Итак, теперь торжественный момент. Перезагружаем систему:

# shutdown -r now

А теперь пробуем подсоединиться к своему серверу удаленно — с другого компьютера сети. Если мы используем Mac OS X или Linux, все необходимое у нас уже есть, достаточно просто открыть Терминал (на Маке лучше воспользоваться не стандартным, а бесплатной утилитой iTerm — она гораздо легче настраивается на корректную работу с русскими буквами) и набрать

$ ssh <имя_пользователя>@<IP_сервера>

В нашем случае:

$ ssh admin@10.0.1.1

Затем в ответ на появившийся запрос укажем пароль.

Пользователям Windows придется установить дополнительную утилиту — SSH-клиент (например, Telneat или PuTTY; первый из них предпочитает О.Островерх, второй — я)

Заметьте, что для выполнения большинства административных задач необходимы права суперпользователя. Чтобы «стать root’ом», следует набрать короткую команду

$ su

Естественно, компьютер затребует при этом ввод пароля суперпользователя.

Постоянно работать от имени root’а, как уже было замечено, неправильно. Поэтому, выполнив задачи, для которых без его прав не обойтись, будем снова «становиться самими собой»:

# exit

Для окончания удаленного сеанса будем использовать команду

$ logout

Для проверки работоспособности шлюза воспользуемся командой ping (результат наверняка не совпадет с моим, главное, чтобы он был):

$ ping -c 5 www.yandex.ru
PING www.yandex.ru (77.88.21.11): 56 data bytes
64 bytes from 77.88.21.11: icmp_seq=0 ttl=56 time=13.068 ms
64 bytes from 77.88.21.11: icmp_seq=1 ttl=56 time=18.085 ms
64 bytes from 77.88.21.11: icmp_seq=2 ttl=56 time=13.922 ms
64 bytes from 77.88.21.11: icmp_seq=3 ttl=56 time=21.465 ms
64 bytes from 77.88.21.11: icmp_seq=4 ttl=56 time=26.112 ms

--- www.yandex.ru ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 13.068/18.530/26.112/4.845 ms

(Если что-то не заладилось, пингуем компьютер локальной сети, потом шлюз провайдера…)

Следующий этап проверки — такие же пинги, но уже с локального компьютера (в Mac OS X/Linux из другого окна Терминала; в Windows — из командной строки DOS). Если в результате получен примерно такой результат, как показано ниже, наш шлюз успешно настроен и уже может быть запущен в работу.

$ ping -c 5 www.ru
PING www.ru (194.87.0.50): 56 data bytes
64 bytes from 194.87.0.50: icmp_seq=0 ttl=55 time=11.073 ms
64 bytes from 194.87.0.50: icmp_seq=1 ttl=55 time=17.107 ms
64 bytes from 194.87.0.50: icmp_seq=2 ttl=55 time=13.78 ms
64 bytes from 194.87.0.50: icmp_seq=3 ttl=55 time=11.197 ms
64 bytes from 194.87.0.50: icmp_seq=4 ttl=55 time=23.407 ms

--- www.ru ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 11.073/15.312/23.407 ms
Опубликовано Михаил К в FreeBSD, 0 комментариев
Справка по редактору vi. Основные команды

Справка по редактору vi. Основные команды

Наиболее распространенные команды консольного текстового редактора vi.

Содержание


Совет: Перед любыми действиями с документом введите следующую команду:

:set showmode


Запуск и завершение VI

vi filenameОткрыть файл filename для редактирования
vi -r filenameОткрыть последнюю сохраненную версию filename после аварийного выхода
vi filename file2Открыть filename, затем file2 … Переход к следующему файлу — :n
ZZ или :wq или 😡Сохранить изменения и завершить VI
:wСохранить изменения в текущем файле
:w!Безусловно сохранить текущий файл
:w fileСохранить текущий файл под именем file
:q!Завершить VI без сохранения

К началу страницы

Режимы

VI работает в командном режиме и режиме ввода. Сразу после запуска редактор находится в командном режиме, в котором можно перемещаться по тексту, выполнять копирование и вставку текста из буфера. Режим ввода включается по командам вставки, дополнения, замены. Нажатие [ESC] возвращает редактор в командный режим. Большинство команд выполняется сразу после нажатия клавиши. Исключение — команды строчного редактора ex, начинающиеся с двоеточия, которые выполняются после нажатия [Return].

К началу страницы

Вставка текста

iВставка перед курсором
IВставка перед строкой
aДобавление за курсором
AДобавление после строки
:r fileВставить содержимое file после текущей строки
В режиме ввода:
CTRL-i или TABВставить смещение вправо на shift width
CTRL-dУменьшить смещение вправо на shift width
CTRL-h или BackspaceУдалить предыдущий символ
CTRL-wУдалить предыдущее слово
CTRL-uУдалить предыдущую строку

К началу страницы

Перемещение по тексту

hВлево
jВниз
kВверх
lВправо
«стрелки»Перемещение по тексту (в больших файлах работает медленно, в некоторых конфигурациях может работать некорректно).
wК следующему слову
bК началу слова
^К первому непробельному символу строки
+ или <cr>К первому символу следующей строки
К первому непробельному символу предыдущей строки
eК концу слова
(К началу предложения
)К концу предложения
{К началу абзаца
}К концу абзаца
Примечание: абзацы разделяются пустой строкой.
0 или |К началу строки
$В конец строки
1GК первой строке файла
GК последней строке файла
HК верхней строке экрана
LК нижней строке экрана
CTRL-dПрокрутка вниз на пол-экрана
CTRL-fПрокрутка вниз на экран
CTRL-uПрокрутка вверх на пол-экрана
CTRL-bПрокрутка вверх на экран
%К парной скобке: ( ), { }, [ ]

К началу страницы

Удаление текста

Большинство команд удаления образуются из символа d и команды перемещения. Например, dw удаляет слово. Другие команды удаления:

xУдалить текущий символ
nxУдалить n символов вправо, начиная с текущего
XУдалить символ слева от курсора
nXУдалить n символов влево от курсора
dd или :dУдалить текущую строку
«(a-z)ddВырезать текущую строку в именованный буфер (от a до z)

К началу страницы

Копирование в буфер

Подобно командам удаления, большинство команд копирования в буфер состоят из символа y и команды перемещения. Например, y$ помещает в буфер конец строки.

yy или :yКопировать текущую строку
«(a-z)yyКопировать текущую строку в именованный буфер (от a до z)

К началу страницы

Изменение текста

Команды изменения действуют как команды удаления с последующим переводом в режим ввода. Большинство из них состоит из символа c и команды перемещения. Например cw заменяет слово.

Вставка из буфера

pПоместить текст из буфера после курсора
PПоместить текст из буфера перед курсором
«(a-z)p или «(a-z)PПоместить текст из буфера (от a до z) после/перед текущей строкой

Буферы

Имя буфера может быть указано перед любой командой удаления, изменения, копирования или вставки. Префикс имеет вид «c, где c — любой символ нижнего регистра. Например, «adw удаляет слово и помещает его в буфер a. Затем его можно будет поместить в текст по команде «ap.

К началу страницы

Поиск/замена подстрок

/strПоиск str вперед от курсора
?strПоиск str назад от курсора
nПовторить поиск в том же направлении
:n,ms/str1/str2/optИскать строку str1 со строки n до m (n и m могут быть опущены); заменить str1 на str2; с опциями opt. Возможные опции: g — глобальный, c — подтверждать замены (y — заменить, <cr> — не заменять), p — печатать измененные строки
&Повторить последнюю команду :s
:g/str1/s/str2/str3/Найти строку, содержащую str1, заменить str2 на str3
;Повторить поиск
,Повторить поиск в обратном направлении

К началу страницы

Регулярные выражения

. (точка)Любой символ, кроме «новой строки»
*0 или более вхождений любого символа
[…]Любой из указанных символов
[^…]Любой из символов, кроме указанных
\<Строго в начале слова
\>Строго в конце слова
^В начале строки
$В конце строки
\(…\)Группа условий
\nЗначение n-ой группы
\Отмена значения спецсимвола (например, \$ позволяет искать символ $)
\\Отмена особого действия символа \

Счетчики

Практически перед любой командой можно указать количество ее повторений. Например, 5dw приведет к удалению 5 слов, а 3fe — к перемещению курсора вперед на 3-е вхождение символа «e». Подобным образом можно действовать и с командами вставки, например, вставить 100 одинаковых строк.

К началу страницы

Режимы VI

Заметьте: вводится :set option для включения режима и :set nooption для выключения. Чтобы установить настройки для каждого запуска VI, в домашнем каталоге создается файл .exrc, содержащий данные команды без двоеточия перед ними.

:set aiАвтоматический отступ (по предыдущей строке)
:set allВывести на экран все режимы
:set ebЗвуковой сигнал при ошибках
:set icИгнорировать регистр при поиске
:set listПоказывать символы табуляции (^l) и конца строки ($)
:set nu
:set number
Показывать номера строк
:set showmodeПоказывать текущий режим в нижней части экрана
:set showmatchПодсвечивать парную открывающую скобку при вводе закрывающей
:set waИсключить нормальную проверку перед записью
:set wm=nУстановить размер правого поля для автопереноса. Для отключения автопереноса n=0

К началу страницы

Макросы

Примечания:

  • Файл «.exrc» в домашнем каталоге может содержать набор макросов, используемый при каждом запуске VI (записываются аналогично командам определения макросов, но без двоеточия).
  • Чтобы включить в макрос управляющий символ, например, ESC, следует предварительно нажать CTRL-v.
  • Чтобы включить в макрос кавычки («), перед ними набирается \ (backslash).
  • Неиспользуемые в vi клавиши: K V Z g q v * = [ ] @ # и функциональные.

Пример (выделены команды VI, которые будут включены в макрос):

:map v /I CTRL-v ESC dwiYou CTRL-v ESC ESC

Действие макроса: При нажатии v найти «I» (/I ESC), удалить слово (dw) и вставить «You» (iYou ESC). CTRL-v нужно для вставки кода ESC

:map key cmd_seqНазначить клавише key исполнение макроса cmd_seq
:mapПоказать в строке состояния все имеющиеся макросы
:unmap keyУдалить макрос
:ab str stringПри вводе сокращения str заменить его на string
:abПоказать все сокращения
:una strОтменить сокращение str

К началу страницы

Прочее

~Смена регистра символа над курсором
JСлияние следующей строки с текущей
nJСлияние n строк
.Повторить последнюю команду, изменяющую текст
uОтменить последнее изменение
UОтменить все изменения в строке
CTRL-GПоказать имя файла, номер строки, общее число строк и положение в файле (%)

К началу страницы

Опубликовано Михаил К в FreeBSD, Linux
Справка по редактору vi

Справка по редактору vi

vi — это консольный текстовый редактор. Фактически стандартный для всевозможных вариантов Linux и Unix. Так что тому, кто собирается серьезно заниматься администрированием таких ОС, уметь обращаться с этой программой крайне желательно. Проблема в том, что работа с vi совершенно непохожа на то, как мы действуем в редакторах с графическим интерфейсом. И, кроме того, тут нет никаких меню, панелей кнопок и даже подсказок. Команды нужно (О, ужас!) помнить.

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

Содержание


Совет: Перед любыми действиями с документом введите следующую команду:

:set showmode


Запуск и завершение VI

Запуск VI
vi filenameОткрыть файл filename для редактирования
view filenameОткрыть файл filename для просмотра
vi -r filenameОткрыть последнюю сохраненную версию filename после аварийного выхода
vi + n filenameОткрыть filename и поместить курсор на строку n
vi + filenameОткрыть filename и поместить курсор на последнюю строку
vi +/string filenameОткрыть filename и поместить курсор на первое вхождение string
vi filename file2Открыть filename, затем file2 … Переход к следующему файлу — :n
Завершение VI
ZZ или :wq или :хСохранить изменения и завершить VI
:wСохранить изменения в текущем файле
:w!Безусловно сохранить текущий файл
:w fileСохранить текущий файл под именем file
:w! fileБезусловно сохранить файл под именем file
:n,mw fileСохранить строки с n до m в file
:n,mw >>fileСохранить строки с n до m в конец file
:qЗавершить VI, предупредив при необходимости сохранения
:q!Завершить VI без сохранения
:e!Начать редактирование снова (отменив несохраненные изменения)
:we!Сохранить и продолжить редактирование

К началу страницы

Статус

:.=Номер текущей строки
:=Количество строк в файле
CTRL-GИмя файла, номер строки, общее число строк и положение в файле (%)
lСпецсимволы в текущей строке: tab (^l), backslash (\), backspace (^H), newline ($), bell (^G), formfeed (^L^)

К началу страницы

Режимы

VI работает в командном режиме и режиме ввода. Сразу после запуска редактор находится в командном режиме, в котором можно перемещаться по тексту, выполнять копирование и вставку текста из буфера. Режим ввода включается по командам вставки, дополнения, замены. Нажатие [ESC] возвращает редактор в командный режим. Большинство команд выполняется сразу после нажатия клавиши. Исключение — команды, начинающиеся с двоеточия, которые выполняются после нажатия [Return].

К началу страницы

Вставка текста

iВставка перед курсором
IВставка перед строкой
aДобавление за курсором
AДобавление после строки
oНовая строка после текущей
OНовая строка перед текущей
rЗаменить символ на символ
RЗамена символов (режим замены)
CTRL-v charвставка управляющих символов (например, ESC и CTRL) до нажатия ESC
Внимание: коды CTRL-Q и CTRL-S обрабатываются операционной системой до передачи VI, поэтому их ввести невозможно.
:r fileВставить содержимое file после текущей строки
:nr fileВставить содержимое file после строки n
В режиме ввода:
CTRL-i или TABВставить смещение вправо на shift width
CTRL-dУменьшить смещение вправо на shift width
CTRL-h или BackspaceУдалить предыдущий символ
CTRL-wУдалить предыдущее слово
CTRL-uУдалить предыдущую строку
CTRL-xУдалить от начала вставленного текста
CTRL-vВставить следующий спецсимвол (т. е. для вставки CTRL-H нужно нажать CTRL-v CTRL-h)

К началу страницы

Перемещение по тексту

hВлево
jВниз
kВверх
lВправо
«стрелки»Перемещение по тексту (в больших файлах работает медленно, в некоторых конфигурациях может работать некорректно).
wК следующему слову
WК следующему слову (по пробелам)
bК началу слова
BК началу слова (по пробелам)
^К первому непробельному символу строки
+ или <cr>К первому символу следующей строки
К первому непробельному символу предыдущей строки
eК концу слова
EК концу слова (по пробелам)
(К началу предложения
)К концу предложения
{К началу абзаца
}К концу абзаца
Примечание: абзацы разделяются пустой строкой.
0 или |К началу строки
n|К позиции n текущей строки
$В конец строки
1GК первой строке файла
GК последней строке файла
nG или :nК n-ой строке файла
fcВперед к символу c
FcНазад к символу c
HК верхней строке экрана
nHК n-ой строке от начала экрана
MК средней строке экрана
LК нижней строке экрана
nLК n-ой строке от конца экрана
CTRL-dПрокрутка вниз на пол-экрана
CTRL-fПрокрутка вниз на экран
CTRL-uПрокрутка вверх на пол-экрана
CTRL-bПрокрутка вверх на экран
CTRL-eПрокрутка на строку вниз
CTRL-yПрокрутка на строку вверх
CTRL-lОбновить экран
z <cr>Сделать текущую строку верхней строкой экрана
nzСделать строку n верхней строкой экрана
z.Сделать текущую строку средней строкой экрана
nz.Сделать строку n средней строкой экрана
z-Сделать текущую строку нижней строкой экрана
nz-Сделать строку n нижней строкой экрана
%К парной скобке: ( ), { }, [ ]

К началу страницы

Удаление текста

Большинство команд удаления образуются из символа d и команды перемещения. Например, dw удаляет слово. Другие команды удаления:

xУдалить текущий символ
nxУдалить n символов вправо, начиная с текущего
XУдалить символ слева от курсора
nXУдалить n символов влево от курсора
DУдалить до конца строки
d$Удалить от курсора до конца строки
dd или :dУдалить текущую строку
ndwУдалить следующие n слов, начиная с текущего
ndbУдалить предыдущие n слов, начиная с текущего
nddУдалить следующие n строк, начиная с текущей
:n,mdУдалить строки с n до m
dMotion_cmdУдалить все, что захватывает команда перемещения (например, dG удаляет текст от текущей позиции до конца файла, а d4 — до конца 4-го предложения).
«(a-z)nddВырезать n строк в именованный буфер (от a до z)
«(a-z)ddВырезать текущую строку в именованный буфер (от a до z)
«npОтменить n-е из последних удалений (последние 9 удалений хранятся в буфере)
«1pu.u.Просмотр буфера удалений, пока не будет возвращено нужное (повторить — u.)

К началу страницы

Копирование в буфер

Подобно командам удаления, большинство команд копирования в буфер состоят из символа y и команды перемещения. Например, y$ помещает в буфер конец строки.

yy или :yКопировать текущую строку
nyy или nYКопировать n строк
yMotion_cmdКопировать текст, захватываемый командой перемещения (например, yG копирует все от текущей позиции курсора до конца файла, а y4 — до конца текущего предложения)
«(a-z)nyyКопировать n строк в именованный буфер (от a до z)
«(a-z)yyКопировать текущую строку в именованный буфер (от a до z)

К началу страницы

Изменение текста

Команды изменения действуют как команды удаления с последующим переводом в режим ввода. Большинство из них состоит из символа c и команды перемещения. Например cw заменяет слово.

CЗаменить от курсора до конца строки
cc или SЗаменить всю текущую строку
xpОбменять символ над курсором и следующий
sЗаменить текущий символ
cwзаменить текущее слово
cMotion_cmdЗаменить текст, захватываемый командой перемещения
<< или >>Сдвинуть строку влево/вправо на shift width (по умолчанию — 8 позиций)
n<< или n>>Сдвинуть n строк влево/вправо на shift width (по умолчанию — 8 позиций)
<Motion_cmd или >Motion_cmdСдвинуть строки, захватываемые командой перемещения, влево/вправо

К началу страницы

Вставка из буфера

pПоместить текст из буфера после курсора
PПоместить текст из буфера перед курсором
«(a-z)p или «(a-z)PПоместить текст из буфера (от a до z) после/перед текущей строкой

К началу страницы

Буферы

Имя буфера может быть указано перед любой командой удаления, изменения, копирования или вставки. Префикс имеет вид «c, где c — любой символ нижнего регистра. Например, «adw удаляет слово и помещает его в буфер a. Затем его можно будет поместить в текст по команде «ap.

К началу страницы

Маркеры

Именованный маркер можно установить на любой строке текста. Именем маркера может быть любой символ нижнего регистра. Маркеры могут использоваться как границы диапазонов.

mcУстановить на строку маркер c
`cК началу строки с маркером c
‘cК первому непробельному символу строки с маркером c

К началу страницы

Поиск/замена подстрок

/strПоиск str вперед от курсора
?strПоиск str назад от курсора
nПовторить поиск в том же направлении
NПовторить поиск в обратном направлении
%Поиск парной скобки: ( ) [ ] или { }
fcПоиск символа c по текущей строке вперед
FcПоиск символа c по текущей строке назад
tcПоиск символа c по строке вперед, курсор устанавливается на предыдущий символ
TcПоиск символа c по строке назад, курсор устанавливается на предыдущий символ
:set icИгнорировать регистр при поиске
:set noicУчиитывать регистр при поиске
:n,ms/str1/str2/optИскать строку str1 со строки n до m (n и m могут быть опущены); заменить str1 на str2; с опциями opt. Возможные опции: g — глобальный, c — подтверждать замены (y — заменить, <cr> — не заменять), p — печатать измененные строки
&Повторить последнюю команду :s
:g/str/cmdВыполнить команду cmd для каждой строки, содержащей str
:g/str1/s/str2/str3/Найти строку, содержащую str1, заменить str2 на str3
:v/str/cmdВыполнить команду cmd для каждой строки, не содержащей str
;Повторить поиск
,Повторить поиск в обратном направлении

К началу страницы

Регулярные выражения

. (точка)Любой символ, кроме «новой строки»
*0 или более вхождений любого символа
[…]Любой из указанных символов
[^…]Любой из символов, кроме указанных
\<Строго в начале слова
\>Строго в конце слова
^В начале строки
$В конце строки
\(…\)Группа условий
\nЗначение n-ой группы
\Отмена значения спецсимвола (например, \$ позволяет искать символ $)
\\Отмена особого действия символа \
[…] — Примеры
[A-Z]Заглавные буквы от A до Z
[a-z]Строчные буквы от a до z
[0-9]Все цифры от 0 до 9
[./=+]Множество, состоящее из . (точки), / (наклонной черты), = и +
[-A-F]Буквы от A до F и минус (минус должен быть указан первым)
[0-9 A-Z]Цифры, пробел и заглавные буквы
[A-Z][a-zA-Z]В первой позиции любая заглавная буква. Во второй позиции любая буква (заглавная или строчная)
[a-z]{m}Поиск m вхождений строчных букв
[a-z]{m,n}Поиск от m до n вхождений строчных букв
Примеры регулярных выражений
/Hello/Строка, содержащая «Hello»
/^TEST$/Строка, точно совпадающая с «TEST»
/^[a-zA-Z]/Строка, начинающаяся с любой буквы
/^[a-z].*/Первый символ строки — cтрочная буква a-z, за которой следует не менее одного символа
/2134$/Строка, заканчивающаяся на «2134»
/\(21|35\)/Строка, содержащая 21 или 35.
Обратите внимание на ( ) и символ вертикальной линии для обозначения операции ИЛИ
/[0-9][0-9]*/Строка, содержащая 1 или более цифр
/^[^#]/Строка, начинающаяся не с «#»
Заметьте: регулярные выражения чувствительны к регистру символов

Счетчики

Практически перед любой командой можно указать количество ее повторений. Например, 5dw приведет к удалению 5 слов, а 3fe — к перемещению курсора вперед на 3-е вхождение символа «e». Подобным образом можно действовать и с командами вставки, например, вставить 100 одинаковых строк.

К началу страницы

Диапазоны

Перед большинством команд, начинающихся с двоеточия, может быть указан диапазон строк, на которые эта команда будет действовать. Например, :3,7d служит для удаления строк 3-7. Диапазоны обычно используются с командой :s для замены в нескольких строках, например, :.,$s/pattern/string/g выполнит замены с текущей строки до конца файла.

:n,mСтроки с n до m
:.Текущая строка
:$Последняя строка
:’cСтрока с маркером c
:%Все строки файла
:g/pattern/Все строки, содержащие pattern

К началу страницы

Обращение к Shell

:! cmdВыполнить команду cmd; возможно использование спецсимволов:

 

% — имя текущего файла

# — имя последнего обработанного файла

!! cmdВыполнить команду cmd; результат поместить в документ, начиная с текущей строки
:!!Выполнить последнюю команду интерпретатора команд
:r! cmdReads and inserts output from cmd
:f fileПереименовать текущий файл в «file»
:w !cmdНазначить текущий файл в качестве входного для команды cmd и исполнить ее
:cd dirСменить рабочую директорию на dir
:shВременно перейти в shell (Возврат в редактор -CTRL-d)
:so fileПрочесть и исполнить команды файла file (file является сценарием shell)
!Motion_cmdПередать текст, захватываемый командой перемещения команде shell cmd
!}sortОтсортировать строки с текущей до конца абзаца

К началу страницы

Файлы

:w fileЗаписать в файл file
:r fileВставить содержимое file после текущей строки
:nК следующему файлу
:pК предыдущему файлу
:e fileРедактировать файл file
!!programЗаменить строку выходными данными program

К началу страницы

Режимы VI

Заметьте: вводится :set option для включения режима и :set nooption для выключения. Чтобы установить настройки для каждого запуска VI, в домашнем каталоге создается файл .exrc, содержащий данные команды без двоеточия перед ними.

:set aiАвтоматический отступ (по предыдущей строке)
:set allВывести на экран все режимы
:set apВыводить текущую строку после команд d c J m :s t u
:set bfУбирать из входных данных управляющие символы (кроме tab)
:set dir=/tmpНазначить /tmp каталогом временных файлов
:set ebЗвуковой сигнал при ошибках
:set icИгнорировать регистр при поиске
:set lispУстанавливать отступы, как принято в Lisp
:set listПоказывать символы табуляции (^l) и конца строки ($)
:set magicПозволить поиск спецсимволов (в регулярных выражениях спецсимволами будут считаться только ^ \ $
:set mesgРазрешить вывод сообщений электронной почты
:set nu
:set number
Показывать номера строк
:set report=nВыводить сообщение, если команда изменяет более n строк (по умолчанию — 5)
:set roСчитать файлы «read only»
:set scroll=nУстановить n строк для CTRL-d и z
:set sh=shell_pathУстановить shell (по умолчанию: /bin/sh) в shell_path
:set showmodeПоказывать текущий режим в нижней части экрана
:set showmatchПодсвечивать парную открывающую скобку при вводе закрывающей
:set sw=nУстановить shift width в n знакомест
:set termПоказать/установить тип терминала
:set terseСокращать сообщения об ошибках
:set timeoutУбрать односекундное ограничение для макросов
:set tl=nSets significance of tags beyond n characters (0 means all)
:set ts=nУстановить для текстового ввода размер табуляции в n
:set waИсключить нормальную проверку перед записью
:set warnПредупреждать: «no write since last change» (последние изменения не сохранены)
:set window=nУстановить число строк в текстовом окне в n
:set wsПри поиске по окончании файла начинать сначала
:set wm=nУстановить размер правого поля для автопереноса. Для отключения автопереноса n=0

К началу страницы

Макросы

Примечания:

  • Файл «.exrc» в домашнем каталоге может содержать набор макросов, используемый при каждом запуске VI (записываются аналогично командам определения макросов, но без двоеточия).
  • Чтобы включить в макрос управляющий символ, например, ESC, следует предварительно нажать CTRL-v.
  • Чтобы включить в макрос кавычки («), перед ними набирается \ (backslash).
  • Неиспользуемые в vi клавиши: K V Z g q v * = [ ] @ # и функциональные.

Пример (выделены команды VI, которые будут включены в макрос):

:map v /I CTRL-v ESC dwiYou CTRL-v ESC ESC

Действие макроса: При нажатии v найти «I» (/I ESC), удалить слово (dw) и вставить «You» (iYou ESC). CTRL-v нужно для вставки кода ESC

:map key cmd_seqНазначить клавише key исполнение макроса cmd_seq
:mapПоказать в строке состояния все имеющиеся макросы
:unmap keyУдалить макрос
:ab str stringПри вводе сокращения str заменить его на string
:abПоказать все сокращения
:una strОтменить сокращение str

К началу страницы

Прочее

~Смена регистра символа над курсором
JСлияние следующей строки с текущей
nJСлияние n строк
.Повторить последнюю команду, изменяющую текст
uОтменить последнее изменение
UОтменить все изменения в строке

К началу страницы


Основой данного материала явилась Advanced Vi Cheat Sheet, взятая с сайта http://www.lagmonster.org/. Информация дополнена и скорректирована с использованием книги: Стен Келли-Бутл. Введение в Unix (пер. с англ.).— М.: «ЛОРИ», 1995, а также Vi Russian FAQ.

Опубликовано Михаил К в FreeBSD, Linux