ISP`s IT Аутсорсинг
Быстрый переход: Главная блога Главная сайта Форум
Если Вы чего то недопоняли или не нашли - задайте
вопрос на нашем форуме и мы попробуем Вам помочь.
ip-as.ru :: Регистрация IP и Автономных систем
Subnets.ru ресурс компании ООО "Меганет-2003" mega-net.ru

Версия для печати Версия для печати

Архивные статьи в категории ‘FreeBSD’

Кто то уже знает, кто-то нет и спит спокойно, точнее пока что спит спокойно.

Как давно вы читали логи своего Asterisk сервера ?

Некоторые из вас или уже видели или ещё увидят в логах строчки:

  • Registration from ‘»100″<sip:100@sip.mydomain.ru>’ failed for ‘188.165.215.79′ – No matching peer found
  • Registration from ‘»111″ <sip:111@sip.mydomain.ru>’ failed for ‘188.165.215.79′ – Wrong password

Догадываетесь к чему они ведут ? К тому что вас сканят и пытаются подобрать пароль к вашим SIP аккаунтам.

Большинство пользователей безалаберно относятся к своим паролям, это факт, а раз так то проверте что на ваших SIP номерах не стоят пароли аля 123 или 1234.

Если пароль таки подберут, то вы (или ваш клиент) попадете на деньги, т.к. через вас пустят звонки забугор, например на Кубу или Северную Корею.

Давайте разберемся как они это делают и попробуем усложнить им жизнь помимо смены паролей к своим SIP аккаунтам.

В сети есть набор утилит sipvicious:

The 4 tools that you should be looking at are:

svmap

svwar

svcrack

svreport

svcrash

The tools:

svmap – this is a sip scanner. When launched against

ranges of ip address space, it will identify any SIP servers

which it finds on the way. Also has the option to scan hosts

on ranges of ports.

svwar – identifies working extension lines on a PBX. A working

extension is one that can be registered.

Also tells you if the extension line requires authentication or not.

svcrack – a password cracker making use of digest authentication.

It is able to crack passwords on both registrar servers and proxy

servers. Current cracking modes are either numeric ranges or

words from dictionary files.

svreport – able to manage sessions created by the rest of the tools

and export to pdf, xml, csv and plain text.

svlearnfp – allows you to generate new fingerprints by simply running

the tool against a host. It will attempt to guess most values and allow

you to save the information to the local fingerprint db. Then you can

choose to upload it to the author so that it can be added to the database.

svcrash – responds to svwar and svcrack SIP messages with a message that

causes old versions to crash.

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

Начнем с того что скачаем этот набор утилит (сохраненная у нас копия).

Распакуйте архив в какую нить папку и можно приступать к скану.

Будет считать что IP-адрес нашего Asterisk сервера это 192.168.1.1  и запустим сканер:

cd /home/virus/sipvicious

./svmap.py -p5060 192.168.1.1 -m INVITE

Получаем результат:

| SIP Device        | User Agent   | Fingerprint |
--------------------------------------------------
| 192.168.1.1:5060 | Asterisk PBX | disabled    |

Идем далее, посканим теперь на аккаунты:

./svwar.py –force -e100-999 192.168.1.1

Ответ может быть таким:

| Extension | Authentication |
------------------------------
| 210       | reqauth        |
| 300       | reqauth        |
| 666       | reqauth        |
| 241       | reqauth        |
| 242       | reqauth        |
| 222       | reqauth        |

Можно ли как то обломать их ? Можно. Для этого отредактируем /usr/local/etc/asterisk/sip.conf и добавим или раскоментируем строчку в секции [general]:

alwaysauthreject = yes

Описание:

When an incoming INVITE or REGISTER is to be rejected, for any reason, always reject with ‘401 Unauthorized’ instead of letting the requester know whether there was a matching user or peer for their request.

Т.е. наш сервер будет всегда при любых ошибках авторизации будет отвечать «401 Unauthorized» и не сообщать подробностей.

После изменения sip.conf зайдите в консоль Asterisk`а:

asterisk -r

и примените изменения:

asterisk*CLI> sip reload

Теперь посканим снова:

./svwar.py –force -e100-999 192.168.1.1

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

WARNING:TakeASip:Bad user = SIP/2.0 401  - svwar will probably not work!
WARNING:TakeASip:We got an unknown response
ERROR:TakeASip:Response: 'SIP/2.0 401 Unauthorized\r\n
Via: SIP/2.0/UDP 192.168.1.1:5061;branch=z9hG4bK-3613016185;received=192.168.1.1;rport=5061\r\n
From: "100"; tag=31303001333430333334313736\r\n
To: "100";tag=as47e73e29\r\nCall-ID: 2008271273\r\n
CSeq: 1 REGISTER\r\n
User-Agent: Asterisk PBX\r\n
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO\r\n
Supported: replaces\r\n
WWW-Authenticate: Digest algorithm=MD5, realm="asterisk", nonce="3b652f8d"\r\n
Content-Length: 0\r\n\r\n'

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

Что ещё мы можем сделать ?

Например закрыть в диал-плане забугорные направления (коды стран), по которым не вы ни ваши пользователи не звонят или вообще перекрыть выход на международку.

Добавим в  /usr/local/etc/asterisk/extensions.conf в секцию где у вас происходит выход в город:

exten => _810X.,1,playback(pbx-invalid)

exten => _810X.,n,Hangup()

Так же мы можем скриптом анализировать логи Asterisk сервера и всех уродов, подбирающих пароль, банить фаирволом (ipfw) сервера.

Нашу версию подобного скрипта можно увидеть пройдя по ссылке: http://subnets.ru/files/protect_aster.txt

Инсталляция скрипта:

1. Сохраните код скрипта на своем сервере

2. Переименуйте файл в protect_aster.sh

3. Сделайте скрипт исполняемым:

chmod a+x protect_aster.sh

4. Добавте в ваш firewall ipfw правило:

ipfw add XXX reject ip from «table(56)» to me

где ХХХ это номер правила.

Будьте внимательны размещая данное правило, не забаньте сами себя ! Обеспечьте allow правила для своих IP-адресов выше этого правила, чтобы избежать неожиданностей.

5. Добавте скрипт на исполнение по crontab, отредактируйте /etc/crontab:

*/5    *       *       *       *       root    /full/path/to/script/protect_aster.sh

Забаненый IP-адрес попадает в таблицу ровно на сутки, через сутки он автоматически будет удален из таблицы.

Надеемся, что эти не хитрые приемы помогут вам остаться при деньгах и сэкономить ваши нервы.

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Авторы: Панфилов Алексей (lehis (at) subnets.ru) и Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

Делалось по статье http://tuxnotes.ru/articles.php?a_id=18
Тут приведу её полностью, со своими комментариями и дополнениями [в квадратных скобках].

В конце статьи будут приведены мои конфиги сервера и клиента.
—————————————————————————————————————

Создание сервера OpenVPN в FreeBSD

Однажды передо мной предстала задача реализации безопасного доступа из внешнего мира к внутренней корпоративной сети. На выходе из корпоративной сети стоял FreeBSD 7.0, в качестве реализации был выбран OpenVPN.
В данной статье я на примере из личной практики опишу процесс создания OpenVPN сервера на системе FreeBSD, с возможностью подключения к нему удаленных пользователей (с различных операционных систем: Windows, Linux, MacOS etc.).

Настройка проводилась на системе FreeBSD версии 7.0, настройка на других версиях аналогична данной.

Адрес внутренней сети – 192.168.1.0/24

1. Установка OpenVPN, создание сертификатов и ключей

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

cd /usr/ports/security/openvpn
make install clean

Далее создаем сертификаты и ключи:

cd /usr/local/share/doc/openvpn/easy-rsa/
[при моей инсталляции требуемые файлы лежали в /usr/local/share/doc/openvpn/easy-rsa/2.0]

Редактируем файл vars, содержащий переменные окружения:

chmod +w vars
vi vars

[также нужно отчмодить и скрипты в каталоге, за исключением файлов *.cnf и текстовых Makefile и README]

затем добавляем в файле vars к переменной export KEY_DIR=$D/keys еще каталог server (для удобства). Должно получиться так:

export KEY_DIR=$D/keys/server
[я не добавлял дополнительный каталог]

Загружаем переменные в оболочку:

sh
. ./vars

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

создаем каталог keys и в нем подкаталог server

mkdir -p keys/server

создаем сертификат для сервера:

chmod +x build-ca
./build-ca

Пример ввода данных:

#./build-ca
Generating a 1024 bit RSA private key
....................++++++
...++++++
writing new private key to 'ca.key'
----- You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

Country Name (2 letter code) [UA]:UA
State or Province Name (full name) [Kiev]:Kharkov
Locality Name (eg, city) [Kiev]:Kharkov
Organization Name (eg, company) [x]:server
Organizational Unit Name (eg, section) []:server
Common Name (eg, your name or your server's hostname) []:server
Email Address [root@localhost]:

Создаем файлы index.txt и serial:

touch /usr/local/share/doc/openvpn/easy-rsa/keys/server/index.txt
echo «00″>/usr/local/share/doc/openvpn/easy-rsa/keys/server/serial

Затем создаем сертификат X.509 для сервера. Всё необходимо заполнить аналогично и добавить строки с указанием пароля и имени организации:

chmod +x build-key-server
./build-key-server server

#./build-key-server server
Country Name (2 letter code) [UA]:UA
State or Province Name (full name) [Kiev]:Kharkov
Locality Name (eg, city) [Kiev]:Kharkov
Organization Name (eg, company) [x]:server
Organizational Unit Name (eg, section) []:server
Common Name (eg, your name or your server's hostname) []:server
Email Address [root@localhost]:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []: your_password
An optional company name []:server

Если все пункты выполнены в строгой последовательности, то далее должно быть предложено скриптом согласиться с созданием сертификатов.

Создаём ключ для клиента:

chmod +x build-key
./build-key client

# ./build-key client
Generating a 1024 bit RSA private key
........++++++
...................................++++++
writing new private key to 'client.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [KG]:UA
State or Province Name (full name) [NA]:Kharkov
Locality Name (eg, city) [BISHKEK]:Kharkov
Organization Name (eg, company) [OpenVPN-TEST]:server
Organizational Unit Name (eg, section) []:client
Common Name (eg, your name or your server's hostname) []:client
Email Address [me@myhost.mydomain]:root@localhost
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:your_password
An optional company name []:client

Стоит заметить, что поле organizationName должно совпадать с тем, которое мы ввели при создании сертификата сервера. В нашем случае это будет имя server.

Создаем ключ Диффи-Хелмана (необходим для безопасной авторизации двух сторон):

chmod +x build-dh
./build-dh

выходим из sh:

exit

Создаем ключ для tls-аутентификации:

openvpn –genkey –secret keys/server/ta.key

создаем каталоги для нашего openvpn-сервера:

cd /usr/local/etc/
mkdir openvpn
cd openvpn/
mkdir keys
mkdir ccd

Переходим в каталог /usr/local/etc/openvpn/keys и копируем в него необходимые для сервера ключи и сертификаты:

cd /usr/local/etc/openvpn/keyscp /usr/local/share/doc/openvpn/easy-rsa/keys/server/ca.crt
cp /usr/local/share/doc/openvpn/easy-rsa/keys/server/dh1024.pem
cp /usr/local/share/doc/openvpn/easy-rsa/keys/server/server.crt
cp /usr/local/share/doc/openvpn/easy-rsa/keys/server/server.key
cp /usr/local/share/doc/openvpn/easy-rsa/keys/server/ta.key

Когда сертификаты и ключи созданы, переходим к настройке OpenVPN-сервера.

2. Настройка сервера

в каталоге /usr/local/etc/openvpn создаем файл конфигурации нашего openvpn-сервера

touch server.conf

#указываем порт, на котором будет работать наш сервер
port 2000
# протокол будет использоваться udp (по идее он работает быстрее чем tcp)
proto udp
# используемый тип устройства и номер
dev tun0
#указываем файл CA
ca /usr/local/etc/openvpn/keys/ca.crt
#указываем файл с сертификатом сервера
cert /usr/local/etc/openvpn/keys/server.crt
#указываем файл с ключем сервера
key /usr/local/etc/openvpn/keys/server.key
#указываем файл Диффи Хельман
dh /usr/local/etc/openvpn/keys/dh1024.pem

#задаем виртуальный IP-адрес сервера и маску подсети, которые будут использоваться в нашем туннеле между сервером и удаленным клиентом
server 10.0.0.0 255.255.255.0

#указываем клиенту маршрут к серверу по виртуальному интерфейсу
push «route 10.0.0.0 255.255.255.0″

# указываем где хранятся файлы с настройками клиентов
client-config-dir ccd

# включаем TLS аутентификацию
tls-server
# указываем tls-ключ, и указываем 0 для сервера, а 1 для клиента
tls-auth keys/ta.key 0
# таймаут до реконекта
tls-timeout 120
auth MD5
# включаем шифрацию пакетов с использованием алгоритма симметричного шифрования Blowfish. Пока не было известно ни одно случая взлома данного алгоритма + он быстрее DES
cipher BF-CBC
[в моём случае шифрование не использовалась и поэтому этот пункт закомменчен]

#указывем, что каждые 10 секунд пинговать удаленный хост, и в случае если, в течении 120 секунд не будет ответа – то разрывать соединение
keepalive 10 120

# сжатие трафика
comp-lzo
[если эта опция используется на одной из сторон, она должна обязательно использоваться и другой стороной. иначе коннект будет рваться на этапе согласования MTU туннеля
между сервером и клиентом
]

# максимум клиентов
max-clients 100

#по умолчанию используется аутентификация пользователей по файлам сертификатов, то есть пользователь у себя хранит файлы сертификатов, соответственно пароль в таком случае не используется. На мой взгляд это не совсем безопасно (т.к. если кому-то удастся заполучить эти сертификаты, то он легко сможет получить доступ к нашей корпоративной сети). Я решил добавить к аутентификации по сертификатам еще и аутентификацию по паролю. Будет использоваться пара логин/пароль пользователя в системе FreeBSD ( которого необходимо заранее создать).
[разумеется, используется пользователь с паролем и без шелла - /usr/sbin/nologin
в случае автора эти логин-пароль при установлении соединения нужно ввести вручную, как сделать это автоматически рассмотрено ниже
]

Для добавления аутентификации по паролю подключаем плагин openvpn-auth-pam (который обычно идет вместе с пакетом OpenVPN):

plugin /usr/local/lib/openvpn-auth-pam.so loginuser nobody
group nobody

# Не перечитывать ключи после получения
# SIGUSR1 или ping-restart
persist-key
# Не закрывать и переоткрывать TUN\TAP
# устройство, после получения
# SIGUSR1 или ping-restart
persist-tun
# логирование (не забудьте создать дирректорию /var/log/openvpn/)
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log

# Уровень информации для отладки
verb 3

затем создаем в каталоге ccd файл с настройками удаленного клиента (имя файла должно строго совпадать с именем сертификата, то есть в нашем случае это имя client) следующего содержания:

push «route 192.168.1.0 255.255.255.0″

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

добавляем в файл /etc/rc.conf следующие строчки, для атоматического запуска openvpn-сервера при загрузке системы

openvpn_enable=»YES»
openvpn_if=»tun»
openvpn_configfile=»/usr/local/etc/openvpn/server.conf»
openvpn_dir=»/usr/local/etc/openvpn»

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

set skip on tun0
pass in inet proto udp from any to $ext_if port 2000 keep state
pass quick on tun0

Не забудьте указать в /etc/rc.conf:

gateway_enable=»YES»

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

[если до этого момента gateway_enable не было в /etc/rc.conf, то что бы применить изменения без перезагрузки выполните: sysctl net.inet.ip.forwarding=1]

Все. На этом настройка нашего сервера закончена.

3. Настройка клиента

С сервера необходимо скопировать созданные ранее сертификаты, но не все, а только необходимые пользователю, а именно: ca.crt, client.crt, client.key, dh1024.pem, ta.key.

В рабочем каталоге OpenVPN на стороне клиента создаем папку keys, куда и копируем вышеприведенные файлы. Затем создаем конфигурационный файл с любым именем, например client.ovpn, со следующим содержимым:

dev tun
proto udp
remote 11.11.11.11
#(вместо 11.11.11.11 необходимо указать внешний IP вашего сервера)
port 2000 #(порт к которому устанавливать соединение)
client
resolv-retry infinite
ca keys/ca.crt
cert keys/client.crt
key keys/client.key
tls-client
tls-auth keys/ta.key 1
auth MD5

auth-user-pass
# команда, указывающая клиенту использовать авторизацию по паролю
cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun

#proxy 192.168.1.50:3128 #Раскомментируйте эту строчку, если вы работаете через прокси-сервер

status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

На этом настройка закончена. Все конфиги брались с рабочего сервера.
Процесс создания OpenVPN-сервера на других системах (Debian, Gentoo, Slackware, *BSD) будет аналогичен данному.
Тем и хорош OpenVPN.

Алексей Михайлов
Специально для tuxnotes.ru

[Мои конфиги сервера и клиента]
——————————————————————————-

Сервер:

local 77.87.200.10
port 2000
proto tcp
dev tun0
ca /usr/local/etc/openvpn/keys/ca.crt
cert /usr/local/etc/openvpn/keys/server.crt
key /usr/local/etc/openvpn/keys/server.key
dh /usr/local/etc/openvpn/keys/dh1024.pem

server 172.20.20.0 255.255.255.0 #примечание: сервер забирает себе при организации тунеля первые два адреса из подсети
push «route 172.20.20.0 255.255.255.0″
client-config-dir ccd
tls-server
tls-auth keys/ta.key 0
tls-timeout 120
auth MD5
#cipher BF-CBC
keepalive 10 120
comp-lzo
max-clients 1
plugin /usr/local/lib/openvpn-auth-pam.so login
user nobody
group nobody
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

#tun-mtu 1450 #примечание: можно регулировать размер MTU (должен быть одинаковым на сервере и на клиенте)

Клиент:

dev tun
proto tcp
remote 77.87.200.10
port 2000
client
resolv-retry infinite
ca keys/ca.crt
cert keys/client.crt
key keys/client.key
tls-client
tls-auth keys/ta.key 1
auth MD5
auth-user-pass
#cipher BF-CBC
ns-cert-type server
comp-lzo
persist-key
persist-tun
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

#tun-mtu 1450 #примечание: см. сервер
auth-user-pass keys/account #примечание: в текстовом файле account двумя отдельными строками хранятся логин и пароль
auth-nocache #примечание: чтобы логин-пароль не оставались на клиентской стороне в памяти

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Автор: Будимиров Максим (madmax (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 2, среднее: 4.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

ЗАМЕТКА

В рамках поднятия IPTV в сети столкнулись с приставкой D-Link DIB-120.

Симптомы

Приставка D-Link DIB-120 при загрузке показывает логотип Alpha и потом черный экран и больше ничего.

Выяснилось

Компания Dlink завезла в Россию партию DIB-120, залитых безбраузерной прошивкой.
Отличить такую приставку можно по ее серийному номеру. Он начинается с Р1Т818.
В приставке прошит статический IP-адрес 192.168.1.1 и она слушает мультикаст группу с адреса 239.60.8.1:37732

Решение проблемы

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

1. Если у вас есть сервер с OS Linux, то можно запустить вещание файла прошивки на  мультикаст адрес 239.60.8.1:37732 с помощью проги amfus.

Положите файлы прошивки и amfus в одну папку, затем создайте в этой же папке конфиг:

DIB120.conf:

a0_rootfs a-fs-cramfs.img V4.03.009 14299136 e6d0e447beed049bb2d41798721f29d7
kernel vmlinuz-7402c0 V4.03.009 1602656 7cc07013cc6ff0ea8f078920175791c1

Затем запустите:

./amfus -d DIB120.conf -m 239.60.8.1:37732 -i 1000 -t 32

2. Можно закачать прошивку с помощью HTTP сервера.  Как это сделать было описано в этой статье, процитирую ее:

По умолчанию IP STB D-Link DIB-120 поставляется без прошивки (при загрузке отображается ALPHA и черный экран).

На форумах говорят, что это «бракованная» партия, а на самом деле это «чистый» аппарат без странички.

Чтобы исправить это можно загрузить в него следующую прошивку 4.04.013_multicast.rar (доступна обновленная прошивка для DIB-120 от 6.11.09 4.05.004_multicast.rar).

Для перепрошивки понадобиться любой WEB сервер (например Apache).

В корневую директорию сервера необходимо сохранить два файла, которые находятся в архиве (a-fs-cramfs.img и vmlinuz-7402c0).

В качестве примера установлен IP сервера (компьютера с установленным Apache) – 192.168.1.2.

Устройство по умолчанию имеет IP 192.168.1.1, для этого в командной строке нужно выполнить команду telnet 192.168.1.1 на запрос имени пользователя необходимо указать root, а пароль пустой.

В командной строке DIB-120 нужно выполнить следующие команды:

cd /tmp

wget http://192.168.1.2/vmlinuz-7402c0
eraseall /dev/mtd2 ; dd if=vmlinuz-7402c0 of=/dev/mtd2

wget http://192.168.1.2/a-fs-cramfs.img
eraseall /dev/mtd0 ; dd if=a-fs-cramfs.img of=/dev/mtd0

reboot

Внимание! После перезагрузки пароль root’a будет изменен (см. файл password.txt в архиве), пароль можно изменить выполнив команду passwd

Оригинал статьи тут: http://cworld.org.ua/2009/09/16/firmware-d-link-dib-120/

Большое спасибо Hades за данную публикацию,  а то у меня FreeBSD и я уже чуть было не озадачился поднятием эмулятора Linux :)

Сделал все как описано в статье, за исключением того, что поднял не Apache, а по быстрому поставил  nginx (/usr/ports/www/nginx).

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

Вот конфиг  nginx.conf:

user   www www;
worker_processes  1;

error_log  logs/error.log;
pid         /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       192.168.1.2:80;
        server_name  localhost;

        location / {
            root   /usr/local/www/nginx;
            index  index.html index.htm;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/local/www/nginx-dist;
        }
    }
}

Уверен, что данная заметка пригодится не только мне.

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

IPIP tunnel Juniper MX-series Routers + static route via IPIP tunnel interface

Появилась тут задача прокинуть между Juniper и FreeBSD сервером IPIP туннель и пророутить через него подсеть IP-адресов.

Как водится начал с чтения документации:

Но как и в предыдущей статье толи я  тупой, толи лыжи не едут, толи они так пишут мануалы  :(

Расскажу как я решил сию «проблему» идя по своим «шагам», т.к. уверен. что не только я, а и кто-то ещё натолкнется на непонимание мануала и кучу, возникающих по мере чтения, вопросов, которые остаются без ответов.

Сначала возник вопрос: «а где взять необходимый интерфейс в джунике ?».

Читаю Tunnel Services Overview:

ipip
Internally generated IP-over-IP interface. This interface is generated by the JUNOS software to handle IP-over-IP encapsulation. It is not a configurable interface.

Смотрю есть ли у меня на джунипере такой. Да  есть, обнаружен интерфейс:

root@juniper> show interfaces ipip

Physical interface: ipip, Enabled, Physical link is Up
Interface index: 11, SNMP ifIndex: 9
Type: IPIP, Link-level type: IP-over-IP, MTU: Unlimited, Speed: Unlimited
Device flags   : Present Running
Interface flags: SNMP-Traps
Input packets : 0
Output packets: 0

Но меня очень напрягают слова «It is not a configurable interface«. Смотрю далее:

ip-0/0/0
Configurable IP-over-IP encapsulation (also called IP tunneling) interface. IP tunneling allows the encapsulation of one IP packet over another IP packet.

Вот это уже ближе, хотя бы указано, что он «Configurable«, но что делать если по show interfaces такого интерфейса нет ??? Блин, приплыли….

Решил попробовать все же отконфигурить интерфейс ipip. Конфигурю его так:
root@juniper# show interfaces ipip

unit 0 {
    tunnel {
        source XX.XX.XX.XX;
        destination YY.YY.YY.YY;
    }
    family inet {
        address 10.255.255.5/30;
    }
}

Где XX.XX.XX.XX это один из внешних IP-адресов джуника, YY.YY.YY.YY внешний IP-адрес FreeBSD сервера, а 10.255.255.5 IP-адрес на туннеле со стороны джунипера.

Коммитим конфигурацию на джунипере и идем на FreeBSD. Конфигуим её:

ifconfig gif0 create mtu 1480 link2 tunnel YY.YY.YY.YY  XX.XX.XX.XX 10.255.255.5 10.255.255.6 netmask 255.255.255.252

С IP-адресами все тоже самое, за исключением того, что ессно они «зеркальные», т.е. идут в другом порядке. 10.255.255.6 IP-адрес на туннеле со стороны FreeBSD.

После этого посмотрим создался ли туннель:
ifconfig gif0

gif0: flags=c051 mtu 1480
        tunnel inet YY.YY.YY.YY --> XX.XX.XX.XX
        inet 10.255.255.6 --> 10.255.255.5 netmask 0xfffffffc

Пробую попинговать с обеих сторон туннельные адреса (10.255.255.X) и результат успешен, с двух сторон пинг ходит.

«УРА !!! Задача решена и так просто !»  - подумал я, но не тут то было…….

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

Делаю это, добавляю мой статический маршут для подсети, которую я хочу роутить через туннель. Прописываю маршрут в секции routing-options static:

route ZZ.ZZ.ZZ.0/29 {
    next-hop 10.255.255.6;
    retain;
}

коммичу изменения и получаю не совсем ожидаемый результат :(

А именно, что с джунипера любой IP-адрес из пророученной подсети пингуется, а вот если пробовать попинговать этот же адрес снаружи, то получаем ответ от джунипера о недоступности сети.

Хм…. что за хрень ? Маршрут для подсети в таблице маршрутизации присутствует и по команде:

root@juniper> show route terse

маршрут виден….. Получается что джунипер отказывается роутить (форвардить) пакеты до этой подсети через себя. Почему ? Потому что ipip «It is not a configurable interface» ?

Лезу в гугл и нахожу похожую проблему: PFE-forwarded IPv6. Не смотря на то, что тут IPv6, а у меня вопрос по IPv4, ответ был найден:

Otherwise the ipip.0 tunnel is only from the RE, which can’t forward transit traffic.

Ну собственно так себя мой джуник и ведет, не форвардит транзитный трафик….

Но я не сдался, лезу снова курить мануалы….. Смотрю в пример «Example: Configuring Unicast Tunnels«:
Configure two unnumbered IP-IP tunnels:

[edit interfaces]
ip-0/3/0 {

    unit 0 {

        tunnel {
            source 192.168.4.18;
            destination 192.168.4.253;
        }

        family inet;
    }

    unit 1 {

        tunnel {
            source 192.168.4.18;
            destination 192.168.4.254;
        }

        family inet;
    }

}

To configure a numbered tunnel interface, include an address under family inet:

[edit interfaces]
ip-0/3/0 {
    unit 0 {
        tunnel {
            source 192.168.4.18;
            destination 192.168.4.253;
        }
        family inet {
            address 10.5.5.1/30;
        }
    }
    unit 1 {
        tunnel {
            source 192.168.4.18;
            destination 192.168.4.254;
        }
        family inet {
            address 10.6.6.100/30;
        }
    }
}

И снова задаюсь вопросом, а откуда они взяли интерфейс ip-0/3/0 ? Почему у них такой интерфейс есть,а у меня нет ! Ведь написано ж, что в MX-серии это встроено:

The MX-series routers support Dense Port Concentrators (DPCs) with built-in Ethernet ports and therefore do not support Tunnel Services PICs. To create tunnel interfaces on an MX-series router, you configure a DPC and the corresponding Packet Forwarding Engine to use for tunneling services at the [edit chassis] hierarchy level. You also configure the amount of bandwidth reserved for tunnel services. The JUNOS software creates tunnel interfaces on the Packet Forwarding Engine. To create tunnel interfaces on MX-series routers, include the following statements at the [edit chassis] hierarchy level

Так, получается, что я должен взять реальный интерфейс и настроить его для работы с tunneling services. Но стоп, у меня нет свободных интерфейсов, все что есть сейчас работают как Ethernet интерфейсы.

Возникает новый резонный вопрос,  а что будет если на отконфигуренном Ethernet интерфейсе добавить настройки и для tunneling services ?

Нашел ответ на этот вопрос вот тут:

The Packet Forwarding Engine of a 10-Gigabit Ethernet 4-port DPC supports either tunnel interfaces or Ethernet interfaces, but not both.

Мда…. опять приплыли… не может интерфейс быть и тунельным и эзернет интерфейсом :(

Неужели сделать то что мне надо невозможно если нет свободного физического интерфейса ?

М.б. меня не отпускали слова «встроенный», а м.б. остатки памяти напомнили текст предыдущей статьи, я не знаю, но полез я выполнять команду:

root@juniper> show chassis hardware

...........
FPC 5            REV 08   XXX-XXXXXX   KDXXXX            DPCE 4x 10GE R
...........
PIC 3                   BUILTIN      BUILTIN           1x 10GE(LAN/WAN)

Опа ! А это уже кое что. Встроенный интерфейс fpc 5 pic 3.
Такс… Снова возникает вопрос: «А м.б. именно этот интерфейс и поможет нам создать туннельный интерфейс ?»

Ответа на этот вопрос я так и не нашел, ни в мануалах, ни в гугле, но следуя тому что уже прочел в мануалах и банальной логике решил попробовать.

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

root@juniper# set chassis fpc 5 pic 3 tunnel-services bandwidth 10g

Получил в конфиге:
root@juniper# show chassis

fpc 5 {
    pic 3 {
        tunnel-services {
            bandwidth 10g;
        }
    }
}
network-services ip;

Так, интерфейс под tunnel services я задал, идем далее.

Попробую создать сам интерфейс:
root@juniper# set interfaces ip-5/3/0 unit 0

Ошибок эта команда не вызвала и интерфейс появился в конфиге. Значит я иду в правильном направлении.

Зададим IP-адреса, по которым и будет строится IPIP туннель:
root@juniper# set interfaces ip-5/3/0 unit 0 tunnel source XX.XX.XX.XX destination YY.YY.YY.YY

Теперь зададим IP-адрес на конце туннеля со стороны джунипера:
root@juniper# set interfaces ip-5/3/0 unit 0 family inet address 10.255.255.5/30

Смотрим что получилось:
root@juniper# show interfaces ip-5/3/0

unit 0 {
    tunnel {
        source XX.XX.XX.XX;
        destination YY.YY.YY.YY;
    }
    family inet {
        address 10.255.255.5/30;
    }
}

Выполняем заветную:
root@juniper# commit check
и получаю радостный для меня ответ:

configuration check succeeds

Ну вот вроде и все. Коммитим изменения и смотрим.

Вот теперь все работает как надо и поставленная задача полностью выполнена:

  • IPIP туннель между  Juniper и FreeBSD создан и работает
  • подсеть IP-адресов статически пророучена через туннель
  • джунипер  форвардит трафик до пророученной статическим маршрутом через IPIP туннель подсети

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (Еще не голосовали)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

Автообзвон

Есть задачи реализация которых возможна через автоматический обзвон. Например ?

Например вы сис.админ, у вас есть локальная сеть и куча оборудования в ней, но вы же не 24/7 на работе, а раз так, то в сети может что то произойти, например событие в системе мониторинга, а вас нет на рабочем месте. Конечно можно отправлять себе SMS, если такая вожможность есть, а имея сервер Asterisk можно и позвонить и самому себе рассказать что же случилось ;)

Или вам необходима система callback, что бы позвонив на номер заведенный на Asterisk, вы могли получить с него обратный звонок и набрать другой номер.

Итак, считаем что у вас у уже есть установленный и настроенный сервер Asterisk, который имеет выход в город.

Что бы совершить автоматический звонок нам потребуется следующие вещи:

  • сформировать call файл
  • иметь в диалплане (dialplan (определяется в /usr/local/etc/asterisk/extensions.conf)) контекст (context) со списком действий

Начнем с call файла, его основной синтаксис:

  • Channel: <channel> – Какой канал использовать для звонка
  • CallerID: «name» <number> – Установить Caller ID, проще сказать тут мы можем выставить АОН (номер с которого мы звоним).
  • MaxRetries: <number> – Максимальное кол-во попыток дозвониться, по умолчанию 0, что является одной попыткой.
  • RetryTime: <number> – Время в секундах между попытками дозвона, по умолчанию 300 (5 минут).
  • WaitTime: <number> – Сколько секунд ожидаем поднятия трубки, по умолчанию 45.
  • Context: <context-name> – Какой контекст используем из extensions.conf
  • Extension: <ext> - Какой экстеншн используем в выбранном контексте (так же в extensions.conf).
  • Priority: <priority> – С какого приоритета начинаем.

Я привел не полный список, полный список доступен тут. Лично я, для каждого номера, создаю свой контекст в extensions.conf.

Соответственно зная синтаксис мы теперь сможем сформировать call файл, на примере звонка через SIP канал:

Channel: SIP/89161112233@sip-provider
Callerid: 9998877
MaxRetries: 2
RetryTime: 20
WaitTime: 60
Context: outgoing_to_89161112233
Extension: s
Priority: 1

Для тех кто в танке :) разберем call файл построчно:

  • позвонить на SIP номер 89161112233 через провайдера sip-provider (имя из /usr/local/etc/asterisk/sip.conf для выхода в город)
  • использовать АОН 9998877
  • Максимальное кол-во попыток дозвона 2
  • Пауза между попытками 20 секунд
  • Ожидать поднятия трубки 60 секунд
  • Использовать контекст (context) с именем outgoing_to_89161112233
  • Начинать с экстеншена (ext) s
  • И начинать с приоритета 1 в экстеншене s

Сформировав call файл, его необходимо положить в папку:  /var/spool/asterisk/outgoing/ сервер Asterisk обнаружив в этой папке файл сразу же попытается отработать его.

Сразу скажу, что можно и задержать обработку файла, т.е. задержать исх. звонок и отложить его на определенное вами время.

Сервер Asterisk смотрит на дату создания call файла и если изменить дату создания на дату в будущем, то Asterisk не будет отрабатывать call файл, пока не наступит эта самая дата.

Как это сделать ? Очень просто, для этого воспользуемся командой touch, которая есть во всех unix системах.

После того как создали сам call файл берем и меняем дату его создания, шаблон даты такой:

ГОДМЕСЯЦДЕНЬЧАСЫМИНУТЫ.СЕКУНДЫ (внимание: перед секундами стоит символ точки, это так и нужно, а не опечатка).

Для примера выставим дату в будущем, скажем это 09.07.2010 19:18:55:

/usr/bin/touch -t 1007091918.55 /path/to/call/file.call

Дата создания call файла изменится и если переместить файл в /var/spool/asterisk/outgoing/, то соответственно Asterisk его не обработает до тех пор пока не наступит выставленная дата.

Совет: генерить call файл лучше в какой то tmp директории, выполнять над ними все необходимые и действия и затем мувить (переносить) в /var/spool/asterisk/outgoing/.

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

[outgoing_to_89161112233]
exten => s,1,Answer
exten => s,n,Wait(1)
exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/welcome)
exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/Down)
exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/provider-a)
exten => s,n,Background(/usr/local/share/asterisk/sounds/monitoring/bye)
exten => s,n,hangup

Исходя из данного контекста Asterisk дозвонившись до 89161112233 (человек взял трубку) выполнит следущее:

  • поднимет трубку со своей стороны
  • секунду подождет
  • проиграет записанные вами звуковые файлы (полные пути к файлам указаны)
  • повесит трубку

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

После того как Asterisk полностью отработает call файл, он его удаляет из директории /var/spool/asterisk/outgoing/.

Callback

Он работает по тому же принципу, что и описанный выше автообзвон, за некоторыми исключениеми:

  • генерация call файла происходит при звонке человека на номер выделенный под callback.
  • в контексте (context) мы не просто проигрываем звуковые, а предлагаем пользователю ввести номер, на который он хочет позвонить

Что нам потребуется в этом случае:

  • выделить номер для callback и создать контекст (context) под него в  extensions.conf.
  • «передать»  звонок в AGI скрипт, который проверит АОН звонящего на предмет разрешен ли этому номеру callback
  • если  callback разрешен, то сформирует call файл.

AGI – это Asterisk Gateway Interface.
Asterisk Gateway Interface это возможность расширить функционал Asterisk`а с помощью использования скриптов на многих языках программирования. Например Perl, PHP, C, Pascal, Bourne Shell.

Начнем с номера, допустим это будет гор. номер 84955556677. Добавим в extensions.conf в контекст (context) куда поступают все входящие звонки:

exten => 84955556677,1,AGI(sms-callback.php)
exten => 84955556677,n,Hangup()

Т.е. звонок на экстеншн (ext) 84955556677 будет передан AGI скрипту sms-callback.php, а затем звонок будет сразу же завершен.

AGI скрипты для Asterisk располагаются в директории  /usr/local/share/asterisk/agi-bin/.

Почему скрипт на PHP ? PHP был выбран для AGI, т.к. callback является неотъемлимой частью проекта написанного на PHP + MySQL, потому решили и AGI пусть на PHP будет.
Сам скрипт: http://subnets.ru/files/sms-callback.php.txt

Что происходит с скрипте ?

  • определяем необходимые переменные
  • получаем данные от Asterisk`а.
  • логи, куда же без них. В лог мы поместим все то, то получил AGI скрипт от Asterisk`а, это для дебага, потом можно выключить логирование.
  • проверяем номер (АОН) звонящего на доступ к callback
  • смотрим нет ли уже call файла для  данного номера, если нет, то создаем его

В переменной $agivar['agi_callerid'] и содержится АОН (телефонный номер) звонящего переданного нам Asterisk`ом, что в других передаваемых переменных вы сможете увидеть в log файле.
Если установить $debug в ноль, то тем самым выключите логирование.
В массиве  $permit_num содержатся номера для которых разрешен callback.

Ну и осталось дело за малым, а именно что бы был контекст (context) под звонящий номер в extensions.conf.

Допустим наш callback номер 84955556677 набрали с мобильного 89105647899 и ему разрешен callback (номер84955556677 указан в массиве  $permit_num в скрипте), то его контекст может выглядеть вот так:

[outgoing_to_89105647899]
exten => s,1,Set(CallbackNumTries=0)
exten => s,n,Set(CALLERID(num)="9998877")
exten => s,n(start),Background(vo-vvedite-ton-num-abonent)
exten => s,n,WaitExten(10)
exten => 100,1,Dial(SIP/8495${EXTEN}@sip-provider,120)
exten => _XXXXXXX,1,Dial(SIP/8495${EXTEN}@sip-provider,120)
exten => _8X.,1,Dial(SIP/${EXTEN}@sip-provider,120)
exten => i,1,Set(CallbackNumTries=$[${CallbackNumTries} + 1])
exten => i,n,Playback(vo-nomer-nabran-ne-verno)
exten => i,n,GotoIf($["${CallbackNumTries}" < "3"]?s|start)
exten => i,n,Playback(vo-dosvidaniya)
exten => t,1,Set(CallbackNumTries=$[${CallbackNumTries} + 1])
exten => t,n,GotoIf($["${CallbackNumTries}" < "3"]?s|start)
exten => t,n,Playback(vo-dosvidaniya)
exten => t,n,Hangup()
  • устанавливаем число попыток в ноль
  • выставляем АОН (под исх. звонок)
  • проигрываем записанный текст: «переведите ваш телефон в тональный набор…. бла… бла.. бла…»
  • 10 сек. ждем от человека набора номера
  • указываем возможный набор номеров: 100 (узнать время ;) ), 7-ми значный номер, 8-рка и далее сколько угодно цифр
  • даем человеку три попытки на набор номера, если истек таймаут набора номера или номер был набран не верно, то человеку это озвучивается и кол-во попыток увеличивается на 1-цу и наше мини голосовое меню начинается сначала (возврат к метке start)
  • если кол-во попыток исчерпано, то Asterisk вешает трубку

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА !

Автор: Николаев Дмитрий (virus (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 2, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

По многочисленным наблюдениям системных администраторов различных компаний
предоставляющих доступ к сети интернет, с начала февраля 2010 года наблюдается
ежедневный лавинообразный рост количества пакетов в сети, их фрагментация, а
также существенный рост исходящего трафика. Данная проблема связана с новой
версией торрент-клиента uTorrent вышедшего 3 февраля 2010 года с поддержкой
протокола uTP, работающего поверх UDP. Призванный снизить нагрузку на
провайдеров протокол uTP в результате привел к обратному эффекту.

Для относительно безболезненной для клиента фильтрации uTP на шлюзе под
управлением Linux рекомендуется использовать следующее правило:

/sbin/iptables -I FORWARD -m udp -p udp -m string --hex-string "|7F FF FF FF AB|" --algo kmp \
      --from 40 --to 44 -m statictic --mode random --probability 0.90 -j DROP

Мониторинг работы правила:

iptables -L FORWARD -nv | grep statist

Для FreeBSD правило будет выглядеть следующим образом:

ngctl mkpeer ipfw: bpf 2 main
   ngctl name ipfw:2 utp_filter
   ngctl msg utp_filter: setprogram { thisHook=\"main\" ifMatch=\"\" ifNotMatch=\"main\" bpf_prog_len=12 bpf_prog=[
      { code=48 jt=0 jf=0 k=0 } { code=84 jt=0 jf=0 k=240 } { code=21 jt=0 jf=8 k=64 } { code=48 jt=0 jf=0 k=9 }
      { code=21 jt=0 jf=6 k=17 } { code=40 jt=0 jf=0 k=6 } { code=69 jt=4 jf=0 k=8191 } { code=177 jt=0 jf=0 k=0 }
      { code=64 jt=0 jf=0 k=20 } { code=21 jt=0 jf=1 k=2147483647 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ] }

   ipfw add 2 netgraph 2 udp from any to any iplen 0-128

Мониторинг:

ngctl msg utp_filter: getstats \"main\"

Оригинал: http://www.opennet.ru/tips/info/2304.shtml

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 5, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

От админа:

Гугля по Инету наткнулся на толковую статью, решил скопировать в блог, дабы сохранить.

ipfw это удобный и гибкий пакетный фильтр, но без внешних средств решение он может принимать только на основе данных в заголовке пакета (ip и udp/tcp). Иногда этого недостаточно и нужно учитывать содержимое пакета. Например у меня возникло желание зафильтровать DNS-запросы MX-записей, которые в большом количестве делают зараженные спамерскими троянами клиентские компьютеры, чем вызывают повышенную загрузку DNS-сервера. В случае если клиентские компьютеры за NAT, почтовых серверов на них быть не должно, и MX-записи им спрашивать не нужно. Правильно ли так делать это отдельный вопрос, здесь будет рассмотрен только технический аспект – как это сделать.

Для решения данной задачи есть как минимум три варианта:
Из ipfw через divert-сокет отправлять пакеты процессу работающему в userspace, который будет слушать divert-сокет и фильтровать приходящие на него пакеты. Главный минус такого варианта – большие накладные расходы и как следствие низкая производительность. Другой минус – этот демон еще нужно написать. Хотя не исключено, что кто то уже написал демон слушающий divert и фильтрующий пакеты через bpf.
ng_bpf – узел Netgraph использующий bpf для фильтрации пакетов
ng_bpf можно подключить непосредственно к ng_ether.
пакеты в ng_bpf можно отправлять из ipfw через ng_ipfw, при выполнении определенного правила через.

Я выбрал последний вариант (ng_ipfw+ng_bpf), несмотря на то, что он несколько сложнее (ниже напишу почему), чем ng_ether+ng_bpf. Во-первых связка ng_ipfw+ng_bpf теоретически должна работать немного быстрее (тесты не проводил), а во вторых из ipfw удобно рулить тем какие пакеты отправлять на дальнейшую обработку в bpf, а какие нет.

bpf

Для начала нужно определиться по какому bpf-выражению будем фильтровать пакеты. Исходная задача звучала так: DNS-запросы (бит QR установлен в 1). Тип запроса – MX. Со вторым сложнее – в одном пакете может быть запрос на несколько записей разных типов, а сами запросы имеют переменную длину, и начинаются со строки заканчивающейся на 0 длина которой не указана в полях. Парсить такой запрос полностью в bpf очень неудобно. Впрочем это и не нужно – запросы посылаемые спамботами содержать запрос только на одну запись типа MX и можно просто заглянуть в конец пакета – там будут поля Type (MX – 0×000f)и Class (IN – 0×0001). Если это проверять, то под правило будут подпадать любые пакеты у которых в конце запрос на MX-запись.

При составлении выражения удобно пользоваться описанием формата пакетов с сайта networksorcery.com 1).

udp[10] & 0×80 = 0 - проверяем, что 1-й бит, байта со смещением 102) выставлен в 1, т. е. то, что это запрос, а не ответ.
udp[udp[4:2]-4 : 4] = 0x000f0001 - последние 4 байта UDP пакета 0x000f0001. udp[4:2] это длинна UDP пакета в байтах (вместе с заголовком).

В результате получается выражение:

udp dst port 53 and udp[10] & 0x80 = 0 and udp[udp[4:2]-4 : 4] = 0x000f0001

Но для ng_bpf нужно не выражение, а bpf-программа – набор низкоуровневых инструкций, которые нужно выполнить для проверки пакета. Чем то напоминает упрощенный и усеченный ассемблер.

В какие инструкции нужно преобразовать выражение зависит от того, что подается на вход bpf-фильтра – IP пакеты (начиная с заголовка IP-пакета без каких либо дополнительных заголовков), ethernet-фреймы (т. е. заголовок канального уровня и далее IP пакет) или пакет какого либо другого канального уровня.

В случае если ng_bpf подключен к ng_ether на его вход подаются ethernet фреймы, и для получения bpf-кода можно воспользоваться способом описанным в man ng_bpf – tcpdump -ddd и последующее приведении в формат который нужен для netgraph с помощью awk.

В случае подключения ng_bpf к ng_ipfw на вход подаются IP пакеты и такой способ не подойдет – в начале будет пара команд проверяющих поле в заголовке ethernet-фрейма которого в нашем случае нету, а в последующих командах будет использовано смещение на 14 байт больше чем нужно.

Поэтому есть два способа – составить программу руками заглядывая в man bpf и /usr/include/net/bpf.h (за основу можно взять вывод tcpdump -ddd, но с нуля написать не сложнее чем вручную дизассемблировать вывод tcpdump -ddd, изменить и потом снова перевести это в bpf-код). Это процесс сильно напоминает программирование на ассемблере с последующим переводом этого в машинные коды.

Или можно написать небольшую программку для компиляции выражения в bpf-код проверки IP пакетов (в libpcap это тип DLT_RAW, т. е. “сырой” IP пакет без каких либо дополнительных заголовков).

Cначала я составил bpf-код вручную, потом решил, что такой способ хорошо только в учебных целях, поскольку отнимает много времени и для повседневной работы не годится.

Потом написал маленькую программку которая это делает используя libpcap:

/*
 * to compile type:
 * gcc -lpcap bpf_comp.c -o bpf_comp
 */

#include <err.h>
#include <pcap.h>
#include <stdio.h>
#include <sysexits.h>

int main(int argc, char *argv[])

{
        struct bpf_program bp;
        unsigned int i;

        if (argc != 2)
                errx(EX_USAGE, "Usage %s 'filter expression'", argv[0]);

        if(pcap_compile_nopcap(65535, DLT_RAW, &bp, argv[1], 1, 0)) {
                errx(EX_USAGE, "filter syntax error");
        }

        printf("bpf_prog_len=%d bpf_prog=[ ", bp.bf_len);

        for (i = 0; i < bp.bf_len; i ++) {
                printf("{ code=%d jt=%d jf=%d k=%d } ",
                        bp.bf_insns[i].code, bp.bf_insns[i].jt, bp.bf_insns[i].jf, bp.bf_insns[i].k);
        }

        printf("]\n");

        exit(0);
}

Для тестирования этой программы можно посмотреть bpf-программу для фильтрации udp пакетов:

:~> ./bpf_comp udp
bpf_prog_len=5 bpf_prog=[ { code=0 jt=0 jf=0 k=0 } { code=48 jt=0 jf=0 k=9 } { code=21 jt=0 jf=1 k=17 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ]

Если у Вас получится программа, не 5 команд (bpf_prog_len=5), а 7, значит libpcap собран с поддержкой IPv6 которая пока реализована не очень хорошо. В результате для DLT_RAW создается фильтрующий код, который кроме интересующих нас пакетов может поймать и лишние (это происходит в libpcap до версии 0.9.5 включительно, а в 0.9.6 это должно быть исправлено, но в любом случае если в сети используется только IPv4, то лучше собирать libpcap без поддержки IPv6, чтобы bpf-программа была короче и быстрее). Поэтому если у вас получилось 7 команд для udp, рекомендую пересобрать без поддержки IPv6:

echo 'NO_INET6=true' >> /etc/make.conf
cd /usr/src/lib/libpcap/
make clean
make
make install

Для интересующего нас выражения получается такая bpf-программа:

:~> ./bpf_comp 'udp dst port 53 and udp[10] & 0x80 = 0 and udp[udp[4:2]-4 : 4] = 0x000f0001'
bpf_prog_len=18 bpf_prog=[ { code=0 jt=0 jf=0 k=0 } { code=48 jt=0 jf=0 k=9 } { code=21 jt=0 jf=14 k=17 } { code=40 jt=0 jf=0 k=6 } { code=69 jt=12 jf=0 k=8191 } { code=177 jt=0 jf=0 k=0 } { code=72 jt=0 jf=0 k=2 } { code=21 jt=0 jf=9 k=53 } { code=80 jt=0 jf=0 k=10 } { code=69 jt=7 jf=0 k=128 } { code=72 jt=0 jf=0 k=4 } { code=20 jt=0 jf=0 k=4 } { code=12 jt=0 jf=0 k=0 } { code=7 jt=0 jf=0 k=0 } { code=64 jt=0 jf=0 k=0 } { code=21 jt=0 jf=1 k=983041 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ]

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

Netgraph

Для использования узлов типа ng_bpf и ng_ipfw нужно загрузить соответствующие модули (если они не были включены в ядро):

:~# kldload ng_ipfw
:~# kldload ng_bpf

Чтобы после перезагрузки они загружались автоматически нужно добавить в /boot/loader.conf:

ng_ipfw_load="YES"
ng_bpf_load="YES"

При загрузке модуля ng_ipfw автоматически создается одни узел с именем ipfw (дополнительные узлы типа ipfw создавать нельзя). Создаем узел типа bpf и подключаем его к ipfw:

:~# ngctl mkpeer ipfw: bpf 1 main

Задаем созданному узлу имя:

~# ngctl name ipfw:1 dns_mx_q_filter

Конфигурируем его:

:~# ngctl msg dns_mx_q_filter: setprogram { thisHook="main" ifMatch="" ifNotMatch="main" bpf_prog_len=17 bpf_prog=[ { code=48 jt=0 jf=0 k=9 } { code=21 jt=0 jf=14 k=17 } { code=40 jt=0 jf=0 k=6 } { code=69 jt=12 jf=0 k=8191 } { code=177 jt=0 jf=0 k=0 } { code=72 jt=0 jf=0 k=2 } { code=21 jt=0 jf=9 k=53 } { code=80 jt=0 jf=0 k=10 } { code=69 jt=7 jf=0 k=128 } { code=72 jt=0 jf=0 k=4 } { code=20 jt=0 jf=0 k=4 } { code=12 jt=0 jf=0 k=0 } { code=7 jt=0 jf=0 k=0 } { code=64 jt=0 jf=0 k=0 } { code=21 jt=0 jf=1 k=983041 } { code=6 jt=0 jf=0 k=65535 } { code=6 jt=0 jf=0 k=0 } ] }

thisHook – хук, входящие пакеты с которого будут фильтроваться заданной программой. ifMatch – хук куда будут отправляться пакеты для которых выполнено условия фильтра. Если задать пустым, то пакеты будут отбрасываться (что в данном случае и требовалось – фильтровать определенные пакеты). ifNotMatch – все остальные пакеты отправляем обратно в ipfw3)

Можно посмотреть, что программа действительно задана:

:~# ngctl msg dns_mx_q_filter: getprogram "main"

Теперь осталось интересующие нас пакеты отправить из ipfw через хук с именем 1 в netgraph. Т. к. к хуку с именем 1 подключен узел типа ng_bpf, то пакеты попадут к нему:

:~# ipfw add 123 netgraph 1 udp from 192.168.0.0/16 to me 53

Для просмотра статистики есть сообщение getstats:

:~# ngctl msg dns_mx_q_filter: getstats "main"
Rec'd response "getstats" (3) from "[4fa]:":
Args:   { recvFrames=16333 recvOctets=977179 recvMatchFrames=9133 recvMatchOctets=512317 xmitFrames=7200 xmitOctets=464862 }

Из 16333 пакетов отправленных правилом ipfw в ng_bpf, 9133 пакетов были запросами на mx-записи.

Для конфигурации ng_ipfw+ng_bpf при загрузке можно положить скрипт в /usr/local/etc/rc.d/ (расширение .sh нужно только во FreeBSD 4, 5. Для 6-ки его лучше убрать).

комментарии по поводу этой заметки можно писать в ЖЖ

1) первоисточник этой информации RFC, но в RFC эта информация представлена не так наглядно и удобно
2) 8 байт, заголовок UDP и 2 байта идентификатор DNS запроса
3) что с ними будет дальше зависит от значения sysctl net.inet.ip.fw.one_pass – либо будет разрешен, либо продолжится проверка следующих правил

Автор: Антон Южанинов, Оригинал: http://citrin.ru/freebsd:ng_ipfw_ng_bpf

От админа:

таким же способом можно отфильтровывать uTP (torrent), пакеты можно увидеть выполнив:

tcpdump -ni IFACE_NAME -n "ip[40:4]=0x7FFFFFFF"

Еще полезные ссылки по теме:

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 2, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

Засада

Столкнулись тут с засадой на одном из серверов.

В сервер вставили дуальную карту Intel Gigabit ET Dual Port Server Adapter, сервер работает шлюзом.

pciconf -lv

igb0@pci0:4:0:0: card=0xa03c8086 chip=0×10c98086 rev=0×01 hdr=0×00
vendor = ‘Intel Corporation’
class = network
subclass = ethernet
igb1@pci0:4:0:1: card=0xa03c8086 chip=0×10c98086 rev=0×01 hdr=0×00
vendor = ‘Intel Corporation’
class = network
subclass = ethernet

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

Если качать с самого сервера, то закачка идет в полную скорость канала (т.е. можно и более 20 МБ/с выжать),

а вот если качать как клиент (через этот сервер), то скорость закачки 50 килобайт и выше ну никак не идет :( ((((

Пробовали драйвера и самой FreeBSD 7.2 так и дрова от Yandex, так и дрова с официального сайта Intel.

Но ситуация не изменялась ни на грамм………

Чего мы тока не делали…… даже бубном стучали админским :) ничего не помогало, даже накатили сервер до  FreeBSD 7.3 PRERELEASE – результат тот же.

Трындец подумали мы……. но:

Сами понимаете, гуглили мы изрядно и вот появился луч надежды, наткнулись на описание той же проблемы на lists.freebsd.org, которая датируется аж:

Mon Jun 8 10:53:08 UTC 2009

Где человек пишет, что ему помогло. А именно:

в /etc/sysctl.conf пишем:

dev.igb.0.enable_lro=0
dev.igb.1.enable_lro=0
dev.igb.0.rx_processing_limit=2048
dev.igb.1.rx_processing_limit=2048

Затем перегружаем сервер, а не правим это налету через sysctl, а иначе не заработает, у нас не заработало, как чел и писал.

И вауля ! Сервер возвращается из ребута и наконец то  все становится как надо ! А именно получаем нормальную скорость через него как клиент.

Если по команде:

sysctl dev.igb.0.enable_lro=0
Вылезает:

sysctl: unknown oid ‘dev.igb.0.enable_lro’

Тогда попробуйте так:

ifconfig igb0 -lro

Итог:

  1. Драйвера с сайта Intel
  2. правка переменных sysctl

Ссылки:

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Авторы: Панфилов Алексей (lehis (at) subnets.ru), Николаев Дмитрий (virus (at) subnets.ru), Будимиров Максим (madmax (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 1, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

От админа:
В продолжение статьи «Теория и настройка DNS сервера (bind) на FreeBSD» один из наших блогеров (vasily86) написал следующую статью, которую и представляю вам с некоторыми моими дополнениями.

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

Примеры:

  • .ru
  • .com
  • .edu

Полный список доменов первого уровня я видел здесь.

Чтобы зарегистрировать там свой домен второго уровня нужно заплатить небольшую денежку (например регистратору www.nic.ru) и вам, при условии незанятости, предоставят его, к примеру yandex.ru.

Домены первых уровней принадлежат организации ICANN, которая и следит за ними.
Наша цель – создать домен первого уровня в нашей локальной сети и заодно настроить DNS сервер.
Итак приступаем! Создадим корневую зону «.vrn«.

В системах UNIX самым популярным DNS сервером является named (bind).

За его функционирование отвечает файл named.conf, который расположен в папке /var/named/etc/namedb (или символическая ссылка /etc/namedb).

options {
         directory       "/etc/namedb";
         pid-file        "/var/run/named/pid";
         dump-file       "/var/dump/named_dump.db";
         statistics-file "/var/stats/named.stats";
         forwarders {
                    195.98.64.65;
                    195.98.64.66;
                    };
         listen-on  {
                    192.168.0.101;
                    127.0.0.1;
                    };
};

zone "." {
         type hint;
         file "named.root";
};

zone "vrn" {
         type master;
         file "vrn.zone";
};

zone "0.168.192.in-addr.arpa" {
         type master;
         file "vrn-reverse.zone";
};

В разделе options основные настроики программы,  здесь нужно изменить ip напротив forwarders вписываем DNS провайдера и listen-on – сюда ip, которые необходимо слушать.

От админа:

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

Далее описываем файлы зон:

Самая главная зона – это зона точка (.) ,  данный файл уже создан и менять его нет необходимости.

А вот следующую зону мы создаём для локальной сети, здесь она называется vrn и описана она в файле vrn.zone ниже:

$TTL 86400
vrn.    IN      SOA     ns1.vrn. n2.vrn. (
                        2009121101
                        86400
                        7200
                        8640000
                        86400 )
        IN      NS      ns1.vrn.

ns1     IN      A       192.168.0.101
ns2     IN      A       192.168.0.101

server  IN      A       192.168.0.101
kil     IN      A       192.168.0.100
roma    IN      A       192.168.0.114
nikita  IN      A       192.168.0.109
katya   IN      A       192.168.0.90
pasha   IN      A       192.168.0.10
dima    IN      A       192.168.0.50

Здесь идёт перечисление соответствия имени и ip.

На этом конфигурирование можно закончить, но для того чтобы задать обратное соответствие мы создали ещё одну зону 0.168.192.in-addr.arpa (т.е. ip следует потом вычислять в обратном направлении 192.168.0.      и последнее число прописывается в файле зоны с именем домена)

От админа:

Подробнее можно прочитать в статье: Записи типа «Pointer». Домен IN-ADDR.ARPA. Делегирование «обратных» зон. Инверсные запросы.

$TTL    3600

@       IN      SOA     ns1.vrn. ns2.vrn. (
                        2009121102
                        3600
                        900
                        3600000
                        3600 )
        IN      NS      ns1.vrn.
        IN      NS      ns2.vrn.

10      IN      PTR     pasha.vrn.
50      IN      PTR     dima.vrn.
90      IN      PTR     katya.vrn.
101     IN      PTR     server.vrn.
100     IN      PTR     kil.vrn.
109     IN      PTR     nikita.vrn.
114     IN      PTR     roma.vrn.

Обратите внимание на имена доменов с точкой!!! roma.vrn. иначе ничего не сработает.

Теперь осталось сохраниться. И пробуем запустить named

/etc/rc.d/named onestart

если на консоли не выпали ошибки, значит всё нормально, исправляем файл /etc/resolv.conf

domain vrn
nameserver 192.168.0.101

где 192.168.0.101 – это ip данной машины. И протестируем командами

ping yandex.ru

ping server.vrn

Если пинг прошёл успешно, то добавим наш named в автозагрузку /etc/rc.conf

named_enable=»YES»

и настроем DNS(указав ip данного сервера) у машин, которые находятся в локальной сети. =)

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА !

Автор: vasily86

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 3, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати

Попала к нам материнская плата INTEL: Intel® Server Board S3420GP

На «мамке» две встроенные сетевые карты:

  • Integrated LAN Embedded Intel® 82574L Gigabit Ethernet Controller
  • Integrated LAN Embedded Intel® 82578DM Gigabit Ethernet Controller

Установили FreeBSD 7.2 (в нашем случае это RELEASE), но из сетевых карт FreeBSD сервер видит только одну и это 82574L, а вот 82578DM не видит…

Смотрим вывод команды и ищем класс «network»:

pciconf -lv

none@pci0:0:25:0:        class=0x020000 card=0x34ec8086 chip=0x10ef8086 rev=0x05 hdr=0x00
    vendor     = 'Intel Corporation'
    class      = network
    subclass   = ethernet

em0@pci0:2:0:0: class=0x020000 card=0x34ec8086 chip=0x10d38086 rev=0x00 hdr=0x00
    vendor     = 'Intel Corporation'
    class      = network
    subclass   = ethernet

Как говорится что и требовалось доказать…. Она есть, но стандартные драйвера от em не подошли, вот она и «висит» как none :(

Что с этим делать ? Ответ один: искать дрова.
«Гугл в руки» и вперед ! Дрова найдены. Вот они: em-6.9.20.tar.gz.

Теперь можно приступать к установке драйверов на FreeBSD сервер.

Распаковываем архив:

tar -xzf em-6.9.20.tar.gz

Переходим в папку с исходками:

cd em-6.9.20/src

Собираем это дело:
make

После окончания сборки в папке появится файл if_em.ko, вот он то нам и нужен.

Переносим его в /boot/modules:
mv if_em.ko /boot/modules

Далее ставим его на загрузку при буте сервера, добавляем строчку в /boot/loader.conf:

echo ‘if_em_load=»YES»‘ >> /boot/loader.conf

Затем, чтобы при пересборке ядра родной драйвер em не собирался добавим в /etc/make.conf:

echo ‘WITHOUT_MODULES=em’ >> /etc/make.conf

Теперь нужно пересобрать ядро без поддержки em, т.е. убрать или закоментарить в ядре строчку:

device         em              # Intel PRO/1000 Gigabit Ethernet Family

После пересборки ядра делаем серверу перезагрузку:

reboot

Сервер поднялся, посмотрим же снова:

pciconf -lv

em0@pci0:0:25:0:        class=0x020000 card=0x34ec8086 chip=0x10ef8086 rev=0x05 hdr=0x00
    vendor     = 'Intel Corporation'
    class      = network
    subclass   = ethernet

em1@pci0:2:0:0: class=0x020000 card=0x34ec8086 chip=0x10d38086 rev=0x00 hdr=0x00
    vendor     = 'Intel Corporation'
    class      = network
    subclass   = ethernet

А вот и наша вторая сетевая карта !

Теперь 82578DM это em0, а 82574L это em1.

Посмотрим вывод ifconfig:

ifconfig -a

em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>metric 0 mtu 1500
        options=399b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_UCAST,WOL_MCAST,WOL_MAGIC>
        ether 00:15:17:ae:0c:d9
        media: Ethernet autoselect (1000baseTX )
        status: active
em1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=399b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_UCAST,WOL_MCAST,WOL_MAGIC>
        ether 00:15:17:ae:0c:d8
        media: Ethernet autoselect (1000baseTX )
        status: active

Все, можно начинать юзание сервера и в хвост и в гриву :)

Ссылки:

Драйвер для em от Yandex: http://people.yandex-team.ru/~wawa/

З.Ы. При копировании статьи ссылка на источник ОБЯЗАТЕЛЬНА ! Пожалуйста, уважайте чужой труд.

Автор: Панфилов Алексей (lehis (at) subnets.ru)

Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 3, среднее: 5.00 из 5)
Loading ... Loading ...
Отправить на почту Отправить на почту Версия для печати Версия для печати