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

Архив за Февраль, 2009

Добро пожаловать в блог! Надеемся, что Вы еще вернетесь.

Заметка

Иногда бывает нужно сменить порт для telnet`а (по умолчанию 23) на какой либо ещё.

Как это сделать ?

Довольно просто.

Войдите в режим enable и:

cisco# conf t
cisco(config)#l ine vty 0 15
cisco(config-line)# rotary 5
cisco(config-line)# exit
cisco(config)# exit
cisco# wri

После выполнения этих команд порт для telnet станет 3005 😉

Проверим:

[root@book ~]# telnet 192.168.38.100 3005

Trying 192.168.38.100...
Connected to 192.168.38.100.
Escape character is '^]'.

User Access Verification
Username:

Вот и все.

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

Автор: Панфилов Алексей (lehis (at) subnets.ru)
Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 3, среднее: 5,00 из 5)
Загрузка...
Отправить на почту Отправить на почту

Появилась задача, организовать конференции в Asterisk.

Все кажется просто, поправить два конфига и вуаля, но на деле все оказалось не просто.

Читаем инструкцию Asterisk cmd MeetMe. Пробуем, получаем облом. Не работает. Почему ? Расскажу как было у меня:

посмотрим, что у нас в подгруженных в Asterisk модулях, для этого зайдем в его CLI:

/usr/local/sbin/asterisk -r

и выполним команду show modules:

Asterisk 1.4.23.1, Copyright (C) 1999 — 2008 Digium, Inc. and others.
Created by Mark Spencer <markster@digium.com>
Asterisk comes with ABSOLUTELY NO WARRANTY; type ‘core show warranty’ for details.
This is free software, with components licensed under the GNU General Public
License version 2 and other licenses; you are welcome to redistribute it under
certain conditions. Type ‘core show license’ for details.
=========================================================================
Connected to Asterisk 1.4.23.1 currently running on core (pid = 13061)

aster*CLI> show modules

у себя я обнаружил, что модуля app_meetme.so в списке нету….

можно выполнить и более предметную команду:

aster*CLI> module show like app_meetme

а в логах честно об этом написано:

pbx_extension_helper: No application ‘MeetMe’

Начинаем гуглить и копать. Выясняется, что для того, чтобы был этот модуль нужно собрать zaptel

Ну чтож… идем в порт asterisk`а, делаем:

  1. cd /usr/ports/net/asterisk
  2. make rmconfig
  3. make

выбираем в списке zaptel и после мейка делаем:

make install

в /usr/local/etc/rc.d появляется файл zaptel:

/usr/local/etc/rc.d/zaptel

дописываем в /etc/rc.conf:

zaptel_enable=»YES»

запускаем:

/usr/local/etc/rc.d/zaptel start

после этого проверяем наличие загруженных модулей zaptel.ko и ztdummy.ko:

/sbin/kldstat

Id Refs Address Size Name
………………
3    5 0xc4fb9000 32000    zaptel.ko
…………………
14 1 0xc62a2000 2000 ztdummy.ko

если не подгрузилось, то они лежат тут: /usr/local/lib/zaptel, подгрузите их руками.

проверяем, что в /usr/local/lib/asterisk/modules появился app_meetme.so.

открываем файл /usr/local/etc/asterisk/modules.conf и добавляем:

load => app_meetme.so

открываем /usr/local/etc/asterisk/meetme.conf и добавляем конференцию:

conf => 501

открываем /usr/local/etc/asterisk/extensions.conf и добавляем экстенш для того, что бы попадать в эту конференцию:

exten => 501,1,MeetMe(501)

т.е. при звонке на внутренний номер 501 мы должны попадать в конференцию с номером 501.

да, замечу, что номер exten и номер конференции могут не совпадать.

Ну чтож, вроде все хорошо и здорово, перезапускаем asterisk:

/usr/local/etc/rc.d/asterisk restart

звоним на номер 501 и слышим: «В настоящий момент вы единственный в этой конференции» и трубка вешается (происходит Hangup)

как говориться «приехали»…..

смотрим в логи и видим:

app_meetme.c:800 build_conf: Unable to open pseudo device

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

Что бы мы не делали, тока менялись ошибки:

app_meetme.c:1022 conf_run: Unable to set flags: Inappropriate ioctl for device

или

app_meetme.c:1756 conf_run: Unable to set buffering information: Bad file descriptor

или

app_meetme.c:1777 conf_run: Error getting conference

или

app_meetme.c: Unable to set flags: Inappropriate ioctl for device

Вот последнее что удалось добиться:

WARNING[4670] app_meetme.c: Unable to set flags: Inappropriate ioctl for device
WARNING[4670] app_meetme.c: Unable to set buffering information: Bad file descriptor
WARNING[4670] app_meetme.c: Unable to set linear mode: Bad file descriptor
WARNING[4670] app_meetme.c: Error getting conference
WARNING[4670] app_meetme.c: Error setting conference
WARNING[4670] app_meetme.c: Error flushing channel
WARNING[4670] app_meetme.c: Failed to read frame: Bad file descriptor

конференция так и не заработала…

Изрядно подустав от этого дела, мы обнаружили что существует альтернатива для app_meetme.so и это app_conference.so.

Читаем Asterisk cmd Conference

Приступаем к инсталлу:

  1. cd /usr/ports/net/asterisk
  2. make extract
  3. cd work/asterisk-1.4.23.1
  4. fetch http://dfn.dl.sourceforge.net/sourceforge/appconference/appconference-2.0.1.tar.gz
  5. tar -zxf appconference-2.0.1.tar.gz
  6. cd appconference-2.0.1
  7. Правим файл Makefile, вот diff:
    --- Makefile    2008-02-26 19:05:57.000000000 +0300
    +++ Makefile.new        2009-02-10 21:03:09.000000000 +0300
    @@ -18,9 +18,9 @@
    #
    
    INSTALL_PREFIX :=
    -INSTALL_MODULES_DIR := $(INSTALL_PREFIX)/usr/lib/asterisk/modules
    +INSTALL_MODULES_DIR := $(INSTALL_PREFIX)/usr/local/lib/asterisk/modules
    
    -ASTERISK_INCLUDE_DIR ?= ../asterisk/include
    +ASTERISK_INCLUDE_DIR ?= /usr/local/include
    
    REVISION = $(shell svnversion -n .)
  8. gmake
  9. gmake install

убеждаемся что файл app_conference.so появился в /usr/local/lib/asterisk/modules/

открываем файл /usr/local/etc/asterisk/modules.conf и добавляем:

load => app_conference

открываем /usr/local/etc/asterisk/extensions.conf и добавляем экстенш для того, что бы попадать в конференцию:

exten => 502,1,Conference(502)

перегружаем asterisk и убеждаемся что модуль подгружен:

aster*CLI> module show like app_conference

Module                         Description                              Use Count
app_conference.so              Channel Independent Conference Applicati 0
1 modules loaded

Основное отличие app_meetme.so и это app_conference.so в том что app_conference.so создает конференцию налету (on the fly) и не требует наличия zaptel.

Экстеншеном 502 мы попадаем в автоматом созданную конференцию 502.

И все РАБОТАЕТ !

Но app_conference.so не полный аналог app_meetme.so. Например не поставить PIN на вход или так же просто записать разговор в конференции. Эти вопросы можно решить с помощью самого asterisk 😉

о PIN: Asterisk cmd Conference в разделе » Setting up conferences».

запись разговора в конференции: Asterisk cmd Monitor

пример записи конференции, extensions.conf :

exten => 502,1,Answer
exten => 502,2,Wait(1)
exten => 502,3,Monitor(wav,myfilename)
exten => 502,4,Conference(502,ps)

Записанные файлы myfilename-in.wav и myfilename-out.wav будут лежать в /var/spool/asterisk/monitor/

Удачных вам конференций !

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

Авторы: Николаев Дмитрий (virus (at) subnets.ru) и Панфилов Алексей (lehis (at) subnets.ru)
Ничего не понялТак себе...Не плохоДовольно интересноОтлично ! То что нужно ! (голосов: 6, среднее: 4,50 из 5)
Загрузка...
Отправить на почту Отправить на почту

Для работы этого примера необходимо иметь подгруженный ng_ipfw.ko

Убедиться в его наличии можно командой:

/sbin/kldstat

Id Refs Address    Size     Name
1   11 0xc0400000 4eddc0   kernel
..........................
7    1 0xc9e22000 2000     ng_ipfw.ko

Если у вас ng_ipfw.ko не загружен, то подгрузите его:

/sbin/kldload /boot/kernel/ng_ipfw.ko

После того как ng_ipfw.ko подгружен, в выводе команды:

/usr/sbin/ngctl list

появится строчка вида:

Name: ipfw Type: ipfw ID: 00000023 Num hooks: 2

Без загруженного ng_ipfw.ko при попытке выполнить команды ngctl`а вы будете получать сообщение:

ngctl: send msg: No such file or directory

а при попытке добавить правило в ipfw получите:

ipfw: getsockopt(IP_FW_ADD): Invalid argument

Настройка ng_nat проста и сводится к простенькому скрипту:

Для примера будем NAT`ить подсеть 172.16.5.96/27 через IP-адрес 192.168.20.8 на внешнем интерфейсе fxp0.

#!/usr/bin/perl

$ip='192.168.20.8';
$iface='fxp0';
$net='172.16.5.96/27';
$cmd=sprintf("/usr/sbin/ngctl -f - << -EOF
mkpeer ipfw: nat 60 out
name ipfw:60 nat
connect ipfw: nat: 61 in
msg nat: setaliasaddr %s
",$ip);
system($cmd);

###добавляем необходимые правила в firewall
$cmd=sprintf("/sbin/ipfw add 1000 netgraph 61 all from any to %s via %s in",$ip,$iface);
system($cmd);
$cmd=sprintf("/sbin/ipfw add 1010 netgraph 60 all from %s to any via %s out",$net,$iface);
system($cmd);

где:
$ip — IP адрес, через который будет работать нат (который смотрит в интернет)
$iface — ваш внешний интерфейс
$net — IP подсеть, которую мы собираемся NAT`ить
netgraph — правило в firewall, аналогично divert, только перенаправляет трафик не в socket, а в ноду netgraph, 60, 61 — адреса исходящего и входящего хуков.

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

###создаем ноду nat и подключаем к ipfw
/usr/sbin/ngctl mkpeer ipfw: nat 60 out 
###даем ноде имя "natA" 
/usr/sbin/ngctl name ipfw:60 natA   
###соединяем входящие и исходящие хуки  для "natA"
/usr/sbin/ngctl connect ipfw: natA: 61 in 
###посылаем управляющее сообщение в виде IP адреса, через который будет работать нат.   
/usr/sbin/ngctl msg natA: setaliasaddr 192.168.20.8   

Если все работает, то мы можем посмотреть вывод следующей команды:

#test:~:ngctl show natA:
Name: nat             Type: nat             ID: 00000029   Num hooks: 2
Local hook      Peer name       Peer type    Peer ID         Peer hook
----------      ---------       ---------    -------         ---------
in                     ipfw            ipfw         00000001        61
out                   ipfw            ipfw         00000001        60

Также можно посмотреть все целиком:

#test:~:ngctl list

Как выключить этот NAT ?

Просто выполнить команду:

#test:~:ngctl shutdown natA:

Заметка:

Если вы хотите запустить NAT на нескольких внешних IP-адресах, но не забывайте изменять имена нод (в примере natA) и номера хуков (в примере 60,61) т.к. они должны быть уникальны для каждого из процессов.

Не путайте in и out в создаваемой ноде и правилах ipfw.

Чтиво:

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

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

Основой данной статьи послужила публикация Дмитрия Шевченко.

Интересная идея заменить множество пайпов в файерволе на механизм предложенный в ng_car.

Для примера,схема такая, имеем:

Сервер FreeBSD, он подключает пользователей по PPPoE через mpd, интерфейс bge0 смотрит вверх.

Но, ВНИМАНИЕ, NAT`а на этом сервере нет, поэтому, зная что:

Шейпируется только исходящий трафик с интерфеса (как и в PF)

читайте эу статью учитывая эти факты.

Итак, до этого момента для шейпа использовался IPFW + PIPE + таблицы и вяглядело примерно так:

05800 pipe 63 ip from any to table(63) out
05900 pipe 93 ip from table(63) to any in
06000 pipe 64 ip from any to table(64) out
06100 pipe 94 ip from table(64) to any in

..........................................

11200 pipe 78 ip from any to table(78) out
11300 pipe 108 ip from table(78) to any in
11400 pipe 256 ip from any to table(16) out
11500 pipe 257 ip from table(16) to any in

и т.д. около 50-ти таблиц, т.к. тарифов множество.

Шейпируется несколько видов трафика:

  • в интернет
  • к локальным ресурсам

Используя IPFW+ ng_car + таблицы все это можно свести к менее громоздкому варианту:

04000 netgraph tablearg ip from table(20) to table(30) out via bge0
04010 netgraph tablearg ip from table(30) to table(20) out via ng*
05000 netgraph tablearg ip from table(10) to not table(30) out via bge0
05010 netgraph tablearg ip from not table(30) to table(10) out via ng*


Разница по загрузке CPU при шейпе на ng_car довольно ощутима.

Рассмотрим этот вариант повнимательнее:

netgraph — это правило действует как divert, только заворачивает оно не в socket, а в ноду netgraph с параметром tablearg.

tablearg — это аргумент в таблице (10 и 20). Он должен быть уникальным для каждого пользователя, именно по этому аргументу создается нода netgraph, которая и будет шейпить (лимитировать скорость) пользователя.

Пример создания таблицы IPFW:

#:test:~:ipfw table 10 add 172.16.10.26/32 10

#:test:~:ipfw table 10 add 172.16.10.27/32 20

#:test:~:ipfw table 10 add 172.16.10.28/32 30

Посмотрим, что получилось:

#:test:~:ipfw table 10 list
172.16.10.26/32 10
172.16.10.27/32 30
172.16.10.28/32 20

Условимся что:
table 10 — IP-адреса с доступом к интернету
table 20 — IP-адреса с доступом к локальным ресурсам
table 30 — IP-адреса самиx локальныx ресурсов
bge0 — верхний интерфес
ng* — нижние интерфейсы пользователей, подключенных через PPPoE (MPD).

Таким образом мы передали управление от ipfw к ng_car посредством 4 правил в файерволе.

Теперь нужно задать каждому IP-адресу определенную полосу.

В mpd есть скрипты up и down, которые отрабатывают при поднятии туннеля и при опускании туннеля.

Вот них то мы и будем нарезать полосы для IP-адресов в момент подключения к серверу.

Для шейпера нужны 3 модуля:

  • ng_ether.ko
  • ng_car.ko
  • ng_ipfw.ko

Посмотреть подгружены ли модули можно по команде:

kldstat

Если их нет, то загружаем командами:

/sbin/kldload /boot/kernel/ng_ether.ko

/sbin/kldload /boot/kernel/ng_car.ko

/sbin/kldload /boot/kernel/ng_ipfw.ko

Если ng_car.ko отсутствует, то можно добыть его установив порт:

Port:   ng_car-0.6
Path:   /usr/ports/net/ng_car
Info:   Netgraph committed access rate node
Maint:  mav@FreeBSD.org

Скрипт UP.pl:

#!/usr/bin/perl

$iface=$ARGV[0];             ###интерфес пользователя
$ip=$ARGV[3];                 ###IP, выдаваемый пользователю
$user=$ARGV[4];              ###логин пользователя
$inet_table=10;                ###таблица с IP-адресами с доступом в интернет
$local_table=20;               ###таблица с IP-адресами c доступом к локальным ресурсам
$shape_inet=20971520;     ###шейп в интернет (бит/с)
$shape_local=8388608;      ###шейп в локалку (бит/с)

###Ищем tablearg IP-адреса в таблицах
$tablearg_inet=`/sbin/ipfw table $inet_table list | awk '/$ip/ \{print \$2\}'`;
$tablearg_local=`/sbin/ipfw table $local_table list | awk '/$ip/ \{print \$2\}'`;

###создаем шейп в интернет
$tablearg=$tablearg_inet;
chomp($tablearg);
$shape=$shape_inet;
$shape_type="inet";
shape($iface,$tablearg,$shape,$shape_type,$user);

###создаем шейп к локальным ресурсам
$tablearg=$tablearg_local;
chomp($tablearg);
$shape=$shape_local;
$shape_type="local";
shape($iface,$tablearg,$shape,$shape_type,$user);

###===функция нарезки шейпа===
sub shape{
            $cbs=$ebs=$shape/8;
            $cmd=sprintf("/usr/sbin/ngctl -f- <<-EOF
                               mkpeer ipfw: car %s upper
                               name ipfw:%s %s_%s
                               connect %s_%s: ipfw: lower %s
                               msg %s_%s: setconf { upstream={ cbs=%d ebs=%d cir=%d greenAction=1 yellowAction=1 redAction=2 mode=2 } downstream={ cbs=%d ebs=%d cir=%d greenAction=1 yellowAction=1 redAction=2 mode=2 } }
                               EOF>>",
            $tablearg,$tablearg,$shape_type,$user,$shape_type,$user,$tablearg+1,$shape_type,$user,$cbs,$ebs,$shape,$ebs,$cbs,$shape);
            `$cmd`;              #Выполняем команду на сервере
}
$shape_inet=20971520;     ###шейп в интернет (байт/с)
$shape_local=8388608;      ###шейп в локалку (байт/с)

в данном случае шейпы взяты в качестве примера.

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

Имя ноды формируется из переменных $shape_type (тип шейпа) и $user (логин пользователя).

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

/usr/sbin/ngctl -f- <<-EOF
mkpeer ipfw: car 10 upper
name ipfw:10 inet_login
connect inet_login: ipfw: lower 11
msg inet_login: setconf { upstream={ cbs=2621440 ebs=2621440 cir=20971520 greenAction=1 yellowAction=1 redAction=2 mode=2 } downstream={ cbs=2621440 ebs=2621440 cir=20971520 greenAction=1 yellowAction=1 redAction=2 mode=2 } }
EOF>>

Где:

mkpeer ipfw: car 10 upper — создаем ноду для пользователя и подключаем ее к модулю ipfw
name ipfw:10 inet_login — именуем ноду (в последствии через это имя можно управлять шейпом пользователя на лету).
connect inet_login: ipfw: lower 11 — соединяем хуки исходящего и входящего интерфейсов

Рзазберем управляющее сообщение:

msg inet_login: setconf { upstream={ cbs=2621440 ebs=2621440 cir=20971520 greenAction=1 yellowAction=1 redAction=2 mode=2 } downstream={ cbs=2621440 ebs=2621440 cir=20971520 greenAction=1 yellowAction=1 redAction=2 mode=2 } }

inet_login — имя ноды, куда направляется управляющее сообщение
cbs — Commited burst size – размер всплеска (в байтах), по умолчанию равен cir/8.
ebs — Exceeded/Peak burst size – превышение размера всплеска (в байтах), по умолчанию равен cbs.
cir — Commited information rate — разрешенная полоса (в битах в секунду).
greenAction — маркер трафика для cbs (man ng_car)
yellowAction — маркер трафика для ebs (man ng_car)
redAction — маркер трафика переполнения разрешенной полосы пропускания (man ng_car)
mode — mode=2 — Аналог Cisco Rate-Limit, mode=3 Аналог Cisco Traffic Shape.

Скрипт DOWN.pl:

#!/usr/bin/perl
$iface=$ARGV[0];
$ip=$ARGV[3];
$user=$ARGV[4];
$shape_type="inet";
shutdown_hook($user,$shape_type);
$shape_type="local";
shutdown_hook($user,$shape_type);

###===функция уничтожения нод для шейпа при отключении пользователя===
sub shutdown_hook{
                 my $hook=sprintf("%s_%s",$shape_type,$user);
                 $cmd=sprintf("/usr/sbin/ngctl shutdown %s:",$hook);
                 `$cmd`;
}

Исполняемая на сервер комманда следующим образом:

/usr/sbin/ngctl shutdown inet_login:

Т.е. выключаем соответствующую ноду.

Если таблицы будут выглядеть так:

#:test:~:ipfw table 10 list
172.16.10.26/32 10
172.16.10.27/32 30
172.16.10.28/32 20


#:test:~:ipfw table 20 list
172.16.10.26/32 5
172.16.10.27/32 25
172.16.10.28/32 15

То после подключения мы увидим следующую картину:

#:test:~:ngctl show ipfw:
Name: ipfw Type: ipfw ID: 00000d00 Num hooks: 4
Local hook Peer name Peer type Peer ID Peer hook
---------- --------- --------- ------- ---------
6 local_login car 00000d3f lower
5 local_login car 00000d3f upper
11 inet_login car 00000d3d lower
10 inet_login car 00000d3d upper

или для отдельного шейпа:

#:test:
~:ngctl show local_login:
Name: star_37735-1 Type: car ID: 00000d50 Num hooks: 2
Local hook Peer name Peer type Peer ID Peer hook
---------- --------- --------- ------- ---------
lower ipfw ipfw 00000d00 6
upper ipfw ipfw 00000d00 5

Осталось прикрутить это к mpd5. Для этого в конфиг mpd5.conf дописываем:

set iface up-script /usr/local/etc/mpd5/UP.pl
set iface down-script /usr/local/etc/mpd5/DOWN.pl

не забудьте указать полный и главное правильный путь до скриптов !

Есть несколько моментов, о которых нужно помнить при построении такой системы:

  1. Нужно внимательно соблюдать синтаксис ngctl команд, при ошибке или даже лишнем пробеле уже может ничего не работать.
  2. tablearg должен быть уникальным.

Чтиво:

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

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