Настройка Asterisk и FreePBX на собственном VPS
Руководство по установке Asterisk и FreePBX на VPS. Настройка SIP-транков, диапазонов RTP-портов и правил Firewall для защиты от сканеров и предотвращения фрода в сети.
Что такое self-hosted VoIP-сервер
Self-hosted VoIP-сервер — это SIP-сервер, работающий на подконтрольном вам VPS. В этом случае ваши вызовы маршрутизируются через вашу собственную машину, а не через сторонний сервис телефонии. VoIP (voice over IP) передает речь в виде UDP-пакетов. SIP (session initiation protocol) — это протокол сигнализации, который устанавливает и завершает вызов. Аудиопоток не передается по SIP, и именно этот факт является причиной большинства проблем, описанных ниже.
Рабочая система состоит из четырех частей.
- Программное обеспечение PBX (private branch exchange). Asterisk — наиболее распространенный выбор. Он хранит внутренние номера и план набора (dialplan).
- Конечные точки (endpoints). Настольные телефоны или софтфоны, которые регистрируются на PBX с использованием имени пользователя и пароля.
- SIP-транк. Платный аккаунт у провайдера, который соединяет вас с телефонной сетью общего пользования и предоставляет в аренду реальные телефонные номера.
- Медиа-путь. Потоки RTP (real-time transport protocol), которые передают аудио по собственным UDP-портам.
Self-hosting PBX не означает self-hosting телефонных номеров. Номера предоставляются оператором связи, и вы по-прежнему платите за каждый номер и за каждую минуту разговора. Вы контролируете маршрутизацию вызовов, голосовую почту, записи разговоров и список внутренних номеров. Вы также несете ответственность за безопасность сервиса, который часто подвергается атакам с целью наживы.
Какие порты нужны для self-hosted VoIP-сервера?
SIP-сигнализация использует порт 5060 для UDP и TCP, а также порт 5061 для SIP поверх TLS (transport layer security). Эти порты используются только для установки соединения. Аудиопоток каждого вызова представляет собой отдельный UDP-поток, передаваемый на порт из диапазона RTP. Asterisk поставляется с примером rtp.conf, в котором заданы rtpstart=10000 и rtpend=20000, а значения по умолчанию, заложенные при компиляции, — 5000 и 31000. Каждый вызов занимает два порта из этого диапазона: один для RTP, другой для RTCP (RTP control protocol).
Именно на этом разделении спотыкается большинство новичков. Вызов устанавливается, на обоих телефонах отображается ответ, но стороны ничего не слышат, так как файрвол разрешает 5060, но отбрасывает все пакеты RTP. Сигнализация и медиапотоки — это разные потоки, поэтому для них требуются разные правила файрвола. Если это различие для вас в новинку, стоит прочитать как работают порты и listening sockets в Linux, прежде чем открывать какие-либо порты.
Сузьте диапазон перед тем, как открывать его. Двадцать тысяч портов — это гораздо больше, чем нужно небольшой системе. Два порта на вызов означают, что диапазона из двухсот портов хватит на сто одновременных вызовов.
[general]
rtpstart=10000
rtpend=10200Примените настройки с помощью sudo asterisk -rx "core reload".
Что выбрать: Asterisk или FreePBX?
Asterisk — это ядро системы. Вы настраиваете его с помощью текстовых файлов в /etc/asterisk и самостоятельно пишете план набора (dialplan). FreePBX — это веб-интерфейс на PHP и JavaScript, который устанавливается поверх Asterisk, генерирует эти файлы за вас и добавляет модули для голосовой почты и очередей вызовов.
Разница, важная для VPS, заключается в управлении сервером. По состоянию на август 2026 года официальный установщик FreePBX 17 требует чистую систему Debian 12 и устанавливает Asterisk, веб-сервер, сервер баз данных и PHP. Если запустить его на сервере, где уже работают другие службы, результат вас не порадует. Выделите для FreePBX отдельный VPS.
wget https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh -O /tmp/sng_freepbx_debian_install.sh
sudo bash /tmp/sng_freepbx_debian_install.shЛог установки находится в /var/log/pbx/freepbx17-install.log — это первое место, куда нужно заглянуть, если скрипт завершил работу преждевременно.
FreePBX является владельцем конфигурационных файлов, которые она генерирует. Если вы вручную отредактируете файл в pjsip.conf на сервере с FreePBX, ваши изменения исчезнут, как только графический интерфейс перезапишет этот файл. FreePBX считывает отдельные файлы, в названии которых есть _custom, для пользовательских настроек, и не вносит в них изменения.
Честный выбор выглядит так. FreePBX предоставляет графический интерфейс и выставляет страницу входа в вашу телефонную систему в публичный интернет. У «чистого» Asterisk вообще нет веб-интерфейса, а каждая настройка — это задокументированная директива, которую можно прочитать в файле и хранить в git. Если вы устанавливаете FreePBX, ограничьте доступ к её веб-порту своим IP-адресом или используйте VPN, так как административный интерфейс АТС — это цель, дающая прямой путь к финансовым потерям.
Примечание о версиях, актуально на август 2026 года: Asterisk 22 — это текущий релиз с долгосрочной поддержкой (LTS), выпущенный в октябре 2024 года и получающий обновления безопасности до октября 2028 года. Asterisk 23 — это стандартный релиз. В репозитории universe дистрибутива Ubuntu 24.04 доступна версия Asterisk 20.6.0.
Установка Asterisk на Ubuntu 24.04
Использование пакета из дистрибутива — самый быстрый способ. Ubuntu предоставляет исправленную версию, которая автоматически запускается через systemd.
sudo apt update
sudo apt install -y asterisk
sudo asterisk -rx "core show version"Сборка из исходного кода позволяет получить актуальный релиз с долгосрочной поддержкой (LTS).
sudo apt update
sudo apt install -y build-essential wget
cd /usr/local/src
sudo wget https://downloads.asterisk.org/pub/telephony/asterisk/asterisk-22-current.tar.gz
sudo tar -xzf asterisk-22-current.tar.gz
cd asterisk-22.*
sudo contrib/scripts/install_prereq install
sudo ./configure
sudo make menuselect
sudo make -j"$(nproc)"
sudo make install
sudo make samples
sudo make config
sudo ldconfigКоманда install_prereq install загружает зависимости для сборки, соответствующие вашему дистрибутиву, а install_prereq test выводит список команд, которые будут выполнены, без внесения изменений в систему. make menuselect открывает меню выбора модулей, где необходимо включить codec_opus в разделе Codec Translators. Выполняйте make samples только при чистой установке, так как эта команда записывает примеры конфигурации в /etc/asterisk. make config устанавливает скрипт инициализации в /etc/init.d/asterisk, после чего systemd управляет им через слой совместимости с SysV, поэтому команда sudo systemctl enable --now asterisk будет работать корректно.
Независимо от выбранного способа, sudo asterisk -rvvv подключается к работающему демону и открывает интерфейс CLI. Выполнение core show version в этом интерфейсе выводит информацию о фактически установленной версии.
Настройка SIP-транка и одного внутреннего номера
PJSIP — это драйвер SIP-каналов в актуальных версиях Asterisk. Его конфигурация находится в /etc/asterisk/pjsip.conf и строится из небольших типизированных секций, которые ссылаются друг на друга по имени. Секции разных типов могут иметь одинаковое имя, поэтому каждый блок ниже называется mytrunk.
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
[mytrunk]
type=registration
outbound_auth=mytrunk
server_uri=sip:sip.example.com
client_uri=sip:1234567890@sip.example.com
retry_interval=60
[mytrunk]
type=auth
auth_type=userpass
username=1234567890
password=REPLACE_WITH_A_LONG_RANDOM_SECRET
[mytrunk]
type=aor
contact=sip:sip.example.com:5060
[mytrunk]
type=endpoint
context=from-trunk
disallow=all
allow=ulaw
outbound_auth=mytrunk
aors=mytrunk
[mytrunk]
type=identify
endpoint=mytrunk
match=sip.example.comОбъект registration отправляет запрос REGISTER, который сообщает провайдеру, куда доставлять ваши вызовы. Объект identify используется для сопоставления входящего от провайдера вызова с этим эндпоинтом по IP-адресу источника; провайдеры обычно публикуют несколько адресов для этого списка. Исходящая регистрация и эндпоинт намеренно разделены: первый сообщает провайдеру ваше местоположение, второй определяет, что происходит с вызовами.
Для настольного телефона требуются еще три объекта.
[6001]
type=endpoint
context=internal
disallow=all
allow=ulaw
auth=auth6001
aors=6001
direct_media=no
[auth6001]
type=auth
auth_type=userpass
username=6001
password=REPLACE_WITH_A_LONG_RANDOM_SECRET
[6001]
type=aor
max_contacts=1direct_media=no оставляет Asterisk в пути прохождения медиапотока. Если его не использовать, Asterisk попытается заставить два эндпоинта передавать RTP напрямую друг другу, что не сработает, если телефон находится за NAT (network address translation) на домашнем роутере. Никогда не делайте пароль совпадающим с номером внутреннего абонента. В примере выше используется password=6001 для номера 6001, чтобы пример был читаемым, однако сканеры в первую очередь проверяют именно такие шаблоны.
Диалплан в /etc/asterisk/extensions.conf определяет, что разрешено делать в каждом контексте.
[internal]
exten => 6001,1,Dial(PJSIP/6001,20)
exten => _9X.,1,Dial(PJSIP/${EXTEN:1}@mytrunk,60)
[from-trunk]
exten => 1234567890,1,Dial(PJSIP/6001,20)
same => n,Hangup()Эти два контекста являются границей безопасности. from-trunk обрабатывает вызовы, поступающие от провайдера, и может вызывать только номер 6001. Он не имеет доступа к шаблону _9X., поэтому внешний вызов не сможет совершить исходящий звонок через ваш транк. Объедините эти контексты, и вы создадите классический путь для мошенничества: злоумышленник звонит на ваш номер, ваш диалплан совершает исходящий вызов за ваш счет, и вы оплачиваете его.
Примените конфигурацию и проверьте её.
sudo asterisk -rx "pjsip reload"
sudo asterisk -rx "pjsip show registrations"
sudo asterisk -rx "pjsip show endpoints"pjsip show registrations должен отображать mytrunk со статусом Registered. Rejected означает, что провайдер отклонил ваши учетные данные. Unregistered означает, что ваш запрос REGISTER остается без ответа, поэтому в этом случае проверьте настройки межсетевого экрана.
Правила межсетевого экрана для SIP и RTP
Сигнальный трафик и медиапотоки требуют различной обработки из-за разного уровня риска. Ограничьте доступ к порту 5060 только теми адресами, которые фактически использует ваш провайдер, и сетями, в которых находятся ваши телефоны.
sudo ufw allow proto udp from 203.0.113.10 to any port 5060
sudo ufw allow proto tcp from 203.0.113.10 to any port 5060
sudo ufw allow 10000:10200/udp
sudo ufw status verboseДиапазон портов RTP невозможно ограничить так же сильно, поскольку медиаданные часто поступают с адресов, отличных от адресов сигнального трафика. Запросите у провайдера их подсети для медиапотоков и ограничьте доступ ими, если они публикуют эту информацию. Поддерживайте размер диапазона только на уровне, необходимом для часов максимальной нагрузки. Политики по умолчанию, порядок правил и остальные принципы работы ufw описаны в руководстве по основам межсетевого экрана ufw для VPS.
Проверьте также настройки IPv6. Если параметр IPV6=no установлен в /etc/default/ufw, ufw не фильтрует IPv6-трафик вовсе, поэтому демон, привязанный к ::, будет доступен по IPv6 без применения каких-либо правил, указанных выше. В статье Открытие портов для IPv6 с помощью ufw объясняются различия между этими двумя семействами протоколов. Большинство провайдеров также предоставляют отдельный сетевой экран в панели управления; он применяется до того, как пакеты достигают VPS, поэтому порт должен быть открыт в обоих местах.
Брутфорс SIP и мошенничество с платными звонками — это не те проблемы, которые можно игнорировать
Разместите порт 5060 на публичном IP-адресе, и сканирование начнется немедленно. Схема всегда одинакова: запросы REGISTER и INVITE с множества исходных адресов, перебирающие распространенные номера добавочных линий с простыми паролями. Asterisk регистрирует каждый сбой, и строка лога выглядит следующим образом.
Request 'REGISTER' from '<sip:1000@198.51.100.20>' failed for '198.51.100.20:5060' (callid: 5f1a5c0d) - No matching endpoint foundПричина, по которой этому следует уделить серьезное внимание — финансовые потери. Украденный добавочный номер используется для совершения дорогостоящих международных звонков, часто на платные номера, владельцы которых делятся прибылью с атакующим, а счет оплачиваете вы, так как звонки были авторизованы вашими учетными данными. Атака выполняется на машинной скорости и обычно происходит ночью.
Шесть мер защиты являются обязательными, а не опциональными.
- Никогда не создавайте добавочный номер, пароль которого совпадает с самим номером или является коротким словом. Сгенерируйте пароль с помощью
openssl rand -base64 24и вставьте его в конфигурацию. - Оставьте анонимные входящие вызовы отключенными. PJSIP по умолчанию отклоняет неидентифицированные вызовы и принимает их только в том случае, если вы создадите endpoint с именем
anonymous. Не создавайте его. - Держите контекст транка отдельно от любого контекста, имеющего право на исходящие вызовы, как показано выше.
- Ограничьте сигнализацию по исходному IP-адресу как в ufw, так и в сетевом файрволе вашего провайдера.
- Установите лимит расходов у вашего SIP-провайдера и отключите международные направления, на которые вы никогда не звоните. Это единственная мера, которая ограничит убытки, если остальные средства защиты подведут.
- Запустите fail2ban для мониторинга логов Asterisk.
Asterisk также может генерировать событие безопасности после повторяющихся неавторизованных запросов с одного адреса. Секция [global] в файле pjsip.conf использует параметры unidentified_request_count (значение по умолчанию — 5) и unidentified_request_period (значение по умолчанию — 5 секунд). В совокупности это означает, что пять неавторизованных запросов с одного адреса в течение пяти секунд создают событие безопасности, на которое может среагировать fail2ban.
Блокировка сканеров с помощью fail2ban
В состав fail2ban уже входит готовый asterisk. Он охватывает порты 5060 и 5061, считывает /var/log/asterisk/messages и по умолчанию использует maxretry = 10. Этот jail неактивен, пока вы не включите его в /etc/fail2ban/jail.local.
[asterisk]
enabled = true
maxretry = 5
findtime = 600
bantime = 86400sudo systemctl restart fail2ban
sudo fail2ban-client status asteriskПри корректной работе команда выводит путь к файлу журнала jail и количество заблокированных в данный момент адресов. Если порт 5060 открыт для публичного доступа, это число перестанет быть нулевым в течение суток. Входящий в комплект фильтр распознает уведомления No matching endpoint found, упомянутые выше, а также структурированные строки SecurityEvent Asterisk. Эти события записываются в отдельный канал журнала, который закомментирован в /etc/asterisk/logger.conf. Раскомментируйте его там и добавьте файл в параметр logpath для данного jail, если хотите использовать эти данные.
[logfiles]
console => notice,warning,error
messages.log => notice,warning,error
security.log => securityПерезагрузите службу журналирования с помощью sudo asterisk -rx "logger reload". Фильтр также поддерживает journalmatch для asterisk.service, поэтому можно использовать бэкенд journal, если вы не хотите хранить отдельные файлы журналов. Установка, структура jail.local и разблокировка ошибочно заблокированного адреса описаны в руководстве по fail2ban для Ubuntu 24.04.
Задержка и выбор кодека на удаленном VPS
Задержка определяется географическим расстоянием, и её невозможно устранить настройками. Рекомендация ITU-T G.114 гласит, что для нормального разговора односторонняя задержка должна составлять менее 150 мс, а значения до 400 мс считаются допустимыми. Аудиосигнал с телефона поступает на ваш VPS, а затем передается провайдеру транков, поэтому при неудачном выборе региона VPS этот путь удваивается. Размещайте сервер ближе к телефонам или к провайдеру. Если приходится выбирать, отдавайте предпочтение близости к телефонам, так как этот сегмент сети обычно проходит через потребительские интернет-каналы, где наиболее выражен джиттер.
Выбор кодека определяет ширину полосы пропускания на один вызов. Каждый кодек в данном случае отправляет пакет каждые 20 мс, что составляет 50 пакетов в секунду. Каждый пакет содержит 40 байт заголовков IP, UDP и RTP поверх аудиоданных.
The data behind this chart
[
{
"label": "G.711 ulaw",
"payload_kbps": 64,
"ip_kbps": 80
},
{
"label": "G.722",
"payload_kbps": 64,
"ip_kbps": 80
},
{
"label": "Opus at 24 kbps",
"payload_kbps": 24,
"ip_kbps": 40
},
{
"label": "G.729",
"payload_kbps": 8,
"ip_kbps": 24
}
]G.711 ulaw является стандартом для большинства транков. Полезная нагрузка составляет 64 кбит/с, а с учетом заголовков активный вызов потребляет 80 кбит/с в каждом направлении. Opus на 24 кбит/с требует 40 кбит/с, а G.729 снижает потребление до 24 кбит/с ценой качества звука и нагрузки на CPU. Эти цифры получены расчетным путем, а не измерениями: скорость полезной нагрузки плюс 40 байт на пакет при частоте 50 пакетов в секунду. Фрейминг Ethernet или VLAN добавляет незначительный объем трафика на физическом уровне.
Транскодирование потребляет ресурсы CPU. Если ваши телефоны и транк поддерживают ulaw, разрешите только этот кодек, и Asterisk будет передавать аудио без изменений. Opus хорошо работает на каналах с потерями, но для транскодирования между Opus и G.711 требуется внешний модуль codec_opus, который выбирается в make menuselect и не собирается по умолчанию.
Что ломается и какие сообщения вы увидите
Вызов проходит, но тишина. RTP-трафик не поступает. Убедитесь, что диапазон портов в rtp.conf совпадает с диапазоном, открытым в межсетевом экране, затем отследите пакеты с помощью sudo tcpdump -ni any udp portrange 10000-10200 во время совершения вызова. Отсутствие пакетов означает, что ваш межсетевой экран или сеть провайдера блокируют их.
Звук только в одну сторону. Одна из сторон отправляет RTP на адрес, который не может его принять; это проблема адресации, а не портов. Если ваш VPS имеет публичный адрес непосредственно на интерфейсе, настройка NAT не требуется. Если провайдер выдал VPS частный адрес с трансляцией один-к-одному, укажите публичный адрес в параметрах транспорта, а ваш частный диапазон — в local_net.
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
local_net=10.0.0.0/8
external_media_address=198.51.100.5
external_signaling_address=198.51.100.5No matching endpoint found в логе. Запрос не совпал ни с одним эндпоинтом по IP-адресу или имени пользователя. Если это сканер, то это нормальное поведение, и fail2ban справится с этим. Если это ваш провайдер, значит, в секции identify не указан адрес, с которого они отправляют вызовы.
Статус регистрации — Rejected. Провайдер отклонил учетные данные в вашей секции auth. Выполните pjsip set logger on в CLI, отследите один запрос REGISTER и ответ на него, затем сравните client_uri и username с данными, которые предоставил провайдер.
В логе совсем нет полезной информации. По умолчанию Asterisk записывает сообщения уровня notice и выше в messages.log. Повысьте уровень логирования с помощью core set verbose 4 и pjsip set logger on на время воспроизведения проблемы, а затем отключите их, так как SIP-логгер записывает каждый пакет.
Перед публикацией в сети
PBX отличается от других сервисов, которые вы размещаете самостоятельно. Ошибка в веб-приложении приводит лишь к недоступности страницы. Ошибка в PBX за несколько часов сна может обернуться огромным счетом за телефонные услуги. Запускайте PBX на отдельном VPS, который не выполняет других задач. Ограничьте доступ к порту 5060 только доверенными IP-адресами, задайте случайные пароли для каждого внутреннего номера и установите лимит расходов для учетной записи транка. Остальные настройки сервера должны соответствовать базовым требованиям безопасности для любого публичного хоста, которые описаны в этом обзоре реальной безопасности VPS.
FAQ
Какие порты нужно открыть для self-hosted VoIP-сервера?
Порт 5060 для SIP-сигнализации по протоколам UDP и TCP, порт 5061 при использовании SIP поверх TLS, а также диапазон UDP-портов для передачи медиапотока RTP. В примере rtp.conf для Asterisk используется диапазон от 10000 до 20000, а значения по умолчанию, заложенные при компиляции, составляют от 5000 до 31000. Каждый вызов занимает два порта из этого диапазона, поэтому диапазон из двухсот портов позволяет обрабатывать сто одновременных вызовов. Откройте RTP-диапазон для UDP, а доступ к порту 5060 ограничьте адресами вашего провайдера и собственными сетями, вместо того чтобы оставлять его открытым для всех.
Стоит ли устанавливать Asterisk отдельно или использовать FreePBX?
Устанавливайте «чистый» Asterisk, если вам нужна минимальная поверхность атаки, конфигурационные файлы, которые можно хранить в git, и вы готовы самостоятельно писать план набора (dialplan). Устанавливайте FreePBX, если вам нужен графический интерфейс для управления внутренними номерами, голосовой почтой и очередями вызовов. По состоянию на август 2026 года установщик FreePBX 17 требует «чистую» систему Debian 12 и самостоятельно устанавливает Asterisk, веб-сервер, сервер баз данных и PHP, поэтому выделите под него отдельный VPS. FreePBX перезаписывает конфигурационные файлы, которыми управляет, поэтому ручные правки следует вносить только в файлы _custom.
Почему после соединения нет звука?
Сигнализация сработала, а передача медиапотока — нет. SIP установил соединение через порт 5060, а аудиопоток — это отдельный поток UDP на порт из диапазона RTP, который где-то блокируется. Убедитесь, что диапазон в rtp.conf совпадает с диапазоном, открытым в вашем межсетевом экране, и проверьте сетевой экран провайдера, а также настройки на самом сервере. Запустите sudo tcpdump -ni any udp portrange 10000-10200 во время вызова: отсутствие пакетов означает, что они блокируются до того, как доходят до сервера.
Как остановить SIP-брутфорс и телефонное мошенничество?
Для каждого внутреннего номера задайте длинный случайный пароль, который не совпадает с самим номером. Держите контекст, используемый вашим транком, отдельно от любого контекста, который может совершать исходящие вызовы, чтобы входящий вызов не мог инициировать исходящий через ваш аккаунт. Ограничьте доступ к порту 5060 адресами вашего провайдера. Включите джейл asterisk в fail2ban, который считывает /var/log/asterisk/messages и блокирует адреса, вызывающие ошибки No matching endpoint found. Установите лимит расходов и заблокируйте неиспользуемые международные направления у вашего провайдера, так как это единственный способ ограничить убытки, если остальные меры защиты не сработают.
Влияет ли удаленное расположение VPS на качество связи?
Да, так как аудиопоток проходит два плеча: от телефона до VPS и от VPS до провайдера транка. Рекомендация ITU-T G.114 гласит, что односторонняя задержка должна быть менее 150 мс, и неудачно расположенный VPS может потратить большую часть этого бюджета только на расстояние. Выбирайте регион, близкий к телефонам, так как этот участок обычно проходит через потребительский интернет, где джиттер проявляется сильнее всего. Выбор кодека не исправляет задержку, он лишь меняет требования к пропускной способности, поэтому G.729 экономит трафик, но не спасет соединение с задержкой 200 мс.