Files
lisglosips/OPENSIPS_INSTALL_NOTES.md

837 lines
24 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenSIPS installation notes
中文说明:OpenSIPS 安装与修复备忘。
This file records the installation performed on workstation `100.93.185.30`
and the missing pieces found afterwards. Use `install-opensips-stack.sh` for a
repeatable production install.
中文说明:这个文件记录了 `100.93.185.30` 工作站上的安装过程、后来补齐的缺失模块,以及生产环境一键安装时应复用的脚本。
## Target stack
中文说明:目标软件栈。
- OS: Ubuntu 24.04 Noble
- OpenSIPS: 3.6.x from `https://apt.opensips.org`
- OpenSIPS Control Panel: 9.3.6
- RTPengine: Ubuntu `rtpengine-daemon`
- Database: MariaDB
- Web server: Apache + PHP
## Production one-shot install
中文说明:生产环境一键安装方式。
Copy `install-opensips-stack.sh` to a fresh Ubuntu 24.04 server and run:
中文说明:把 `install-opensips-stack.sh` 拷贝到一台全新的 Ubuntu 24.04 服务器上,然后执行下面命令。
```bash
sudo -E SIP_IP=YOUR_SERVER_IP DB_PASS='CHANGE_ME' bash install-opensips-stack.sh
```
Useful variables:
中文说明:下面这些环境变量可以按生产环境修改,例如服务器 IP、数据库密码、MI 端口、RTPengine 端口范围、Monit 账号等。
```bash
SIP_IP=100.93.185.30
SIP_DOMAIN=100.93.185.30
DB_NAME=opensips
DB_USER=opensips
DB_PASS=opensipsrw
CP_VERSION=9.3.6
MI_HTTP_IP=127.0.0.1
MI_HTTP_PORT=8888
RTPENGINE_NG=127.0.0.1:2223
RTPENGINE_PORT_MIN=30000
RTPENGINE_PORT_MAX=40000
MONIT_IP=127.0.0.1
MONIT_PORT=2812
MONIT_USER=admin
MONIT_PASS=monit
```
After installation:
中文说明:安装完成后,OpenSIPS-CP 管理页面和默认账号如下。
```text
OpenSIPS-CP: http://YOUR_SERVER_IP/cp/
Default user: admin
Default pass: opensips
```
Change the OpenSIPS-CP admin password before production use.
中文说明:生产环境必须修改 OpenSIPS-CP 默认管理员密码,避免后台被默认口令登录。
## Startup and boot enablement
中文说明:服务启动和开机自启。
OpenSIPS itself is a systemd service:
中文说明:OpenSIPS 本体是 systemd 服务,下面命令用于设置开机自启、重启、查看是否运行和是否启用。
```bash
sudo systemctl enable opensips
sudo systemctl restart opensips
systemctl is-active opensips
systemctl is-enabled opensips
```
Expected result:
中文说明:期望看到 `active``enabled`,表示服务正在运行并已设置开机启动。
```text
active
enabled
```
OpenSIPS-CP is the web control panel at:
中文说明:OpenSIPS-CP 是 Web 管理后台,通过 `/cp/` 访问。
```text
http://YOUR_SERVER_IP/cp/
```
It is served by Apache and uses MariaDB, so there is no separate
`opensips-cp.service` to enable. Enable and start these services instead:
中文说明:OpenSIPS-CP 不是独立服务,它依赖 Apache 提供网页、MariaDB 存配置和数据,所以要启用的是 `apache2``mariadb`
```bash
sudo systemctl enable apache2 mariadb
sudo systemctl restart mariadb
sudo systemctl restart apache2
systemctl is-active apache2 mariadb
systemctl is-enabled apache2 mariadb
```
Expected result:
```text
active
active
enabled
enabled
```
Useful verification commands:
中文说明:下面命令用于确认 SIP 端口、Web 端口、CP 页面和 MI HTTP 接口都正常。
```bash
ss -lunp | grep ':5060'
ss -ltnp | grep ':80'
curl -fsSI http://127.0.0.1/cp/
curl -fsS -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"ps"}'
```
On the current workstation, the public access URL is:
中文说明:当前这台工作站的访问地址如下。
```text
http://100.93.185.30/cp/
```
## Packages that must not be missed
中文说明:容易漏装但必须安装的软件包。
Base OpenSIPS packages:
中文说明:OpenSIPS 主程序、CLI、MySQL、认证和 TLS 相关基础包。
```bash
opensips
opensips-cli
opensips-mysql-module
opensips-auth-modules
opensips-tls-module
```
Database schema package:
中文说明:OpenSIPS 数据库建表脚本包。
```bash
opensips-mysql-dbschema
```
This one is easy to miss. Without it, `/usr/share/opensips/mysql/*.sql` is not
available and `opensipsdbctl` may not exist on OpenSIPS 3.6 installs.
中文说明:这个包很容易漏。没有它就找不到 `/usr/share/opensips/mysql/*.sql`,后续建表和导入模块表会很麻烦。
OpenSIPS-CP MI support:
中文说明:OpenSIPS-CP 通过 MI 接口控制 OpenSIPS,下面两个包提供 HTTP MI 和 JSON 支持。
```bash
opensips-http-modules
opensips-json-module
```
These provide `httpd.so`, `mi_http.so` and JSON support. Without them,
OpenSIPS-CP actions such as `Reload on Server` will fail when configured for
`json:127.0.0.1:8888/mi`.
中文说明:没有这些模块时,CP 页面里的 `Reload on Server` 会连不上 `127.0.0.1:8888/mi` 或提示 MI 命令不可用。
SIP user authentication and database registration:
中文说明:SIP 用户认证和注册落库需要的模块。
```bash
opensips-auth-modules
opensips-mysql-module
```
Enable these modules in `opensips.cfg`:
中文说明:在 `opensips.cfg` 中启用认证模块和位置服务模块,让用户可以用数据库账号注册到 OpenSIPS。
```opensips
loadmodule "auth.so"
loadmodule "auth_db.so"
modparam("auth_db", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("auth_db", "calculate_ha1", 1)
loadmodule "usrloc.so"
modparam("usrloc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("usrloc", "working_mode_preset", "single-instance-sql-write-through")
```
Then protect REGISTER requests:
中文说明:下面这段用于保护 REGISTER 请求;没有正确账号密码的终端不能注册。
```opensips
if (is_method("REGISTER")) {
if (!www_authorize("$fd", "subscriber")) {
www_challenge("$fd", "auth");
exit;
}
if (!save("location"))
xlog("failed to register AoR $tu\n");
exit;
}
```
`calculate_ha1=1` lets OpenSIPS calculate the digest hash from the plain
`subscriber.password` column created by OpenSIPS-CP.
中文说明:`calculate_ha1=1` 表示 OpenSIPS 可以根据 `subscriber.password` 明文密码计算 SIP Digest 认证需要的 hash。
Dialog tracking for the OpenSIPS-CP Dialog page:
中文说明:Dialog 页面用于查看在线通话/会话状态,需要启用 `dialog.so`
```opensips
loadmodule "dialog.so"
modparam("dialog", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("dialog", "profiles_no_value", "inbound;outbound")
modparam("dialog", "profiles_with_value", "caller;callee")
```
Create dialog state for initial INVITEs:
中文说明:初始 INVITE 到来时创建 dialog 状态,并把主叫、被叫等信息放进 profile,便于 CP 页面查看。
```opensips
if (is_method("INVITE")) {
create_dialog();
set_dlg_profile("outbound");
set_dlg_profile("caller", "$fU");
set_dlg_profile("callee", "$rU");
do_accounting("log");
}
```
Without `dialog.so`, OpenSIPS-CP Dialog pages fail with:
中文说明:如果没加载 `dialog.so`,Dialog 页面会报下面这个 MI 方法不存在。
```text
MI command failed with code -32601 (Method not found)
```
Validation:
中文说明:验证 Dialog MI 命令是否可用。
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"dlg_list"}'
```
Dispatcher support for the OpenSIPS-CP Dispatcher page:
中文说明:Dispatcher 页面用于管理/查看后端服务器分发列表,需要启用 `dispatcher.so`
```opensips
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("dispatcher", "persistent_state", 1)
```
Without `dispatcher.so`, OpenSIPS-CP Dispatcher pages fail with:
中文说明:如果没加载 `dispatcher.so`Dispatcher 页面会报下面这个 MI 方法不存在。
```text
MI command failed with code -32601 (Method not found)
```
Validation:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"ds_list"}'
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"ds_reload"}'
```
Dynamic Routing support for the OpenSIPS-CP Dashboard and Dynamic Routing pages:
中文说明:Dynamic Routing 是动态路由/LCR 能力,用于管理落地网关、路由规则、网关状态,也支撑 Dashboard 的动态路由小组件。
```opensips
loadmodule "drouting.so"
modparam("drouting", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("drouting", "drd_table", "dr_gateways")
modparam("drouting", "drr_table", "dr_rules")
modparam("drouting", "drg_table", "dr_groups")
modparam("drouting", "drc_table", "dr_carriers")
```
The Dashboard `Dynamic Routing` widget calls MI commands such as
`dr_gw_status` and `dr_reload_status`. Without `drouting.so`, Dashboard may show:
中文说明:Dashboard 上的 `Dynamic Routing` 卡片会调用 `dr_gw_status` 等命令;如果没加载 `drouting.so`Dashboard 会出现 Method not found。
```text
MI command failed with code -32601 (Method not found)
```
Validation:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"dr_gw_status"}'
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"dr_reload_status"}'
```
On a fresh system with no dynamic-routing gateways configured, `dr_gw_status`
should return an empty `Gateways` list, not `Method not found`.
中文说明:新系统没有配置网关时,返回空网关列表是正常的;错误是 `Method not found`,说明模块没加载。
RTPengine:
中文说明:RTPengine 是媒体代理,负责 RTP 媒体流转发、NAT 穿透,也可配合录音。
```bash
rtpengine-daemon
```
OpenSIPS-CP has two separate media relay pages:
中文说明:OpenSIPS-CP 里 RTPProxy 和 RTPEngine 是两个不同页面,分别对应不同 OpenSIPS 模块。
- `RTPProxy` uses the OpenSIPS `rtpproxy.so` module and MI commands such as
`rtpproxy_show`, `rtpproxy_reload`, and `rtpproxy_enable`.
- `RTPEngine` uses the OpenSIPS `rtpengine.so` module and MI commands such as
`rtpengine_show`, `rtpengine_reload`, and `rtpengine_enable`.
If either module is not loaded, its page fails with:
中文说明:对应模块没加载时,页面会报 MI 命令不存在。
```text
MI command failed with code -32601 (Method not found)
```
For this workstation, RTPengine is the actual media proxy daemon. RTPProxy is
loaded only so the OpenSIPS-CP RTPProxy page can call its MI commands; without
RTPProxy sockets configured, the page should show an empty list instead of a
Method not found error.
中文说明:当前工作站实际使用的是 RTPengine。RTPProxy 模块只是为了让 CP 的 RTPProxy 页面不报错;没有配置 RTPProxy socket 时显示空列表是正常的。
OpenSIPS module config:
中文说明:下面配置同时启用 `rtpengine.so``rtpproxy.so`,分别对应两个 CP 页面。
```opensips
loadmodule "rtpengine.so"
modparam("rtpengine", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("rtpengine", "db_table", "rtpengine")
loadmodule "rtpproxy.so"
modparam("rtpproxy", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("rtpproxy", "db_table", "rtpproxy_sockets")
```
RTPengine DB row used on the current workstation:
中文说明:当前工作站的 RTPengine 控制 socket 是 `udp:127.0.0.1:2223`,需要写入 `rtpengine` 表。
```sql
INSERT INTO rtpengine (socket, set_id)
SELECT 'udp:127.0.0.1:2223', 0
WHERE NOT EXISTS (
SELECT 1 FROM rtpengine WHERE socket='udp:127.0.0.1:2223' AND set_id=0
);
```
Validation:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"rtpengine_show"}'
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"rtpproxy_show"}'
```
## OpenSIPS-CP SIP Trace page
中文说明:OpenSIPS-CP 的 SIP Trace 页面。
The SIP Trace page displays SIP messages captured by OpenSIPS and stored in the
`sip_trace` table. It is useful for troubleshooting registration, INVITE call
setup, routing, authentication challenges, and failed SIP responses. It lets
you filter by:
中文说明:SIP Trace 用于查看 OpenSIPS 抓到的 SIP 报文,适合排查注册失败、呼叫不通、路由错误、认证失败和 SIP 响应异常。
- `RegExp`: text or regex to search in captured SIP messages.
- `Call ID`: one SIP dialog/transaction identifier.
- `Traced User`: the trace attribute saved by the script, here `$fU`.
- `Start Date` / `End Date`: time range.
- `Group results by Call ID`: groups multiple SIP messages from the same call.
If the page shows:
中文说明:如果 SIP Trace 页面出现下面的错误,说明 `trace` MI 命令不存在。
```text
MI command failed with code -32601 (Method not found)
```
then OpenSIPS-CP called the `trace` MI command, but OpenSIPS did not load the
`tracer.so` module.
中文说明:原因是 CP 调用了 `trace` 命令,但 OpenSIPS 没加载 `tracer.so`
OpenSIPS module config:
中文说明:下面配置开启 tracer 模块,并把 trace 数据写入 MySQL 的 `sip_trace` 表。
```opensips
loadmodule "tracer.so"
modparam("tracer", "trace_on", 1)
modparam("tracer", "trace_id", "[tid]uri=mysql://opensips:opensipsrw@localhost/opensips;table=sip_trace;")
```
Main route hook used on the current workstation:
中文说明:仅启用模块还不会自动写入数据,路由脚本里需要调用 `trace()`
```opensips
route{
trace("tid", "m", "sip", "$fU");
```
The `trace` MI command only toggles tracing on/off. The `trace()` call in the
routing script is what actually writes messages to the `sip_trace` database
table.
中文说明:MI 的 `trace` 命令只是开关;真正把 SIP 消息写进数据库的是路由脚本中的 `trace()` 函数。
Validation:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"trace"}'
mysql -D opensips -e "SELECT COUNT(*) FROM sip_trace;"
```
SIP Trace can grow quickly on a busy server. In production, keep it disabled by
default or clean old rows regularly.
中文说明:生产环境要谨慎开启 SIP Trace,因为话务量大时 `sip_trace` 表会增长很快,应定期清理或只在排障时开启。
Web/database dependencies:
中文说明:Web 前端和数据库依赖包。
```bash
mariadb-server mariadb-client
apache2 libapache2-mod-php
php php-cli php-mysql php-gd php-pear php-apcu php-curl php-xml php-mbstring
git unzip curl
```
Monit support for the OpenSIPS-CP Monit page:
中文说明:Monit 页面用于查看服务器服务和系统状态,需要安装 `monit`
```bash
monit
```
OpenSIPS-CP's Monit page is a proxy to Monit's own HTTP interface. If `monit`
is not installed or the OpenSIPS-CP box has no `monit_conn`, the page may show:
中文说明:CP 的 Monit 页面实际是代理访问 Monit 自带 HTTP 页面;如果 Monit 没装或 CP 的 box 没配置 `monit_conn`,就会报空地址。
```text
Failed to parse address ""
Error: 1
I can't connect!
```
Configure Monit to listen locally:
中文说明:Monit 只监听本机 `127.0.0.1:2812`,避免暴露到外网。
```monit
set httpd port 2812 and
use address 127.0.0.1
allow 127.0.0.1
allow admin:monit
```
Enable it:
```bash
sudo monit -t
sudo systemctl enable monit
sudo systemctl restart monit
```
Configure the OpenSIPS-CP default box:
中文说明:把 OpenSIPS-CP 默认 box 的 Monit 连接地址、账号和密码写入数据库。
```sql
UPDATE ocp_boxes_config
SET monit_conn='127.0.0.1:2812',
monit_user='admin',
monit_pass='monit',
monit_ssl=0
WHERE id=1;
```
Validation:
```bash
systemctl is-active monit
systemctl is-enabled monit
ss -ltnp | grep ':2812'
curl -fsS -u admin:monit http://127.0.0.1:2812/ | grep -m1 Monit
```
On the current workstation, Monit is installed, enabled, and bound to
`127.0.0.1:2812`. The OpenSIPS-CP default box uses `admin` / `monit`.
中文说明:当前工作站已经安装并启用 Monit,CP 使用 `admin / monit` 连接本机 Monit。生产环境请修改密码。
## OpenSIPS config added during the fix
中文说明:安装后补加到 OpenSIPS 配置里的关键修复项。
The initial installation only had `mi_fifo`. OpenSIPS-CP was configured to call:
中文说明:最初只有 `mi_fifo`,但 CP 配置的是 JSON HTTP MI,所以页面 reload 会失败。
```text
json:127.0.0.1:8888/mi
```
So `Reload on Server` failed with:
中文说明:因此 CP 页面点击 `Reload on Server` 时会连接不上 8888 端口。
```text
Failed to connect to 127.0.0.1 port 8888
```
The fix was to load HTTP MI:
中文说明:修复方法是加载 `httpd.so``mi_http.so`,让 OpenSIPS 提供本地 HTTP MI 接口。
```opensips
loadmodule "httpd.so"
modparam("httpd", "ip", "127.0.0.1")
modparam("httpd", "port", 8888)
loadmodule "mi_http.so"
modparam("mi_http", "root", "mi")
```
After that, the MI endpoint worked, but `address_reload` returned:
中文说明:HTTP MI 通了以后,`address_reload` 又报方法不存在,这是因为还没加载权限模块。
```text
Method not found
```
That command is provided by `permissions.so`, so the next fix was:
中文说明:`address_reload``permissions.so` 提供,所以需要加载 permissions 模块并配置数据库。
```opensips
loadmodule "db_mysql.so"
loadmodule "permissions.so"
modparam("permissions", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("permissions", "address_table", "address")
```
Validation command:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"address_reload"}'
```
Expected result:
中文说明:期望返回 OK。
```json
{"jsonrpc":"2.0","result":"OK","id":1}
```
## OpenSIPS-CP Addresses page
中文说明:OpenSIPS-CP 的 Addresses 页面。
The Addresses page writes to the `address` table used by the `permissions`
module.
中文说明:Addresses 页面配置的是 IP 访问规则/白名单类规则,写入 `permissions` 模块使用的 `address` 表。
It is not where the local OpenSIPS listening IP is configured. The listening IP
belongs in:
中文说明:这里不是配置 OpenSIPS 本机监听 IP 的地方;本机监听 IP 要写在 `opensips.cfg``socket`
```text
/etc/opensips/opensips.cfg
```
Example:
```opensips
socket=udp:100.93.185.30:5060
```
Typical Address entry:
中文说明:典型地址规则示例如下。
```text
Group: 1
IP: 47.97.162.65
Mask: 32
Port: 5060
Protocol: any
Pattern:
Context Info: lisglo
```
Notes:
中文说明:字段注意事项。
- `Group` must be numeric.
- `Pattern` is an optional wildcard pattern used by `permissions` matching.
- `Context Info` is returned to the OpenSIPS script when the rule matches.
- Click `Reload on Server` after editing Addresses.
## OpenSIPS-CP Domains validation issue
中文说明:OpenSIPS-CP Domains 页面表单校验问题。
On OpenSIPS-CP 9.3.6, the Domains page may reject both IP addresses and normal
FQDNs in the `SIP Domain` field. The symptom is a red validation icon next to
the field and the `Add New Domain` button stays disabled.
中文说明:在 OpenSIPS-CP 9.3.6 中,Domains 页面可能错误拒绝 IP 和普通域名,表现为输入框旁边红色校验图标,添加按钮不可点。
This is not a SIP limitation. SIP domains may be IPs or FQDNs, and the Domains
tool itself says:
中文说明:这不是 SIP 协议限制,SIP domain 可以是 IP,也可以是 FQDN 域名。
```text
A SIP Domain to be considered local by OpenSIPS - can be an IP or a FQDN
```
The issue is in the browser-side form validation generator:
中文说明:问题在 CP 前端表单校验生成器。
```text
/var/www/html/opensips-cp/web/common/forms.php
```
The code uses `preg_quote()` when embedding validation regexes into JavaScript.
That escapes the regex into a literal string, so JavaScript's `RegExp()` no
longer receives the intended regex.
中文说明:代码用 `preg_quote()` 把正则转给 JavaScript,导致正则被转义成普通字符串,浏览器端校验失效。
Patch:
中文说明:下面补丁把 `preg_quote()` 改成更适合 JS 字符串的 `addslashes()`
```bash
sudo cp -a /var/www/html/opensips-cp/web/common/forms.php \
/var/www/html/opensips-cp/web/common/forms.php.bak.regexfix.$(date +%Y%m%d%H%M%S)
sudo python3 - <<'PY'
from pathlib import Path
p = Path('/var/www/html/opensips-cp/web/common/forms.php')
s = p.read_text()
s = s.replace("preg_quote($re, '/')", "addslashes($re)")
s = s.replace("preg_quote($value['validation_regex'], '/')", "addslashes($value['validation_regex'])")
p.write_text(s)
PY
php -l /var/www/html/opensips-cp/web/common/forms.php
```
On some OpenSIPS-CP 9.3.6 installs, the Domains page can still reject input
after the common form-generator patch because the Domains template ships its
own over-escaped field regex. If both IPs and normal FQDNs still show a red
validation icon, patch the Domains form itself:
中文说明:有些安装即使修了通用表单生成器,Domains 页面自己的字段正则仍然会过度转义,需要单独修 Domains 模板。
```bash
sudo cp -a /var/www/html/opensips-cp/web/tools/system/domains/template/domains.form.php \
/var/www/html/opensips-cp/web/tools/system/domains/template/domains.form.php.bak.domain-regex.$(date +%Y%m%d%H%M%S)
sudo python3 - <<'PY'
from pathlib import Path
p = Path('/var/www/html/opensips-cp/web/tools/system/domains/template/domains.form.php')
s = p.read_text()
lines = []
for line in s.splitlines():
if '"domain", "n", $domain_form' in line:
indent = line[:len(line) - len(line.lstrip())]
lines.append(indent + '"domain", "n", $domain_form[\'domain\'], 128, null);')
else:
lines.append(line)
p.write_text('\n'.join(lines) + '\n')
PY
php -l /var/www/html/opensips-cp/web/tools/system/domains/template/domains.form.php
sudo systemctl reload apache2 || sudo systemctl restart apache2
```
This only disables the browser-side regex for the `SIP Domain` field; the field
remains required, and the database/OpenSIPS domain module still determine what
is actually usable. After patching, hard refresh the browser with `Ctrl+F5`.
中文说明:这个修复只关闭 SIP Domain 字段的浏览器端正则,字段仍是必填;真正是否可用仍由数据库和 OpenSIPS domain 模块决定。修完后浏览器要 `Ctrl+F5` 强制刷新。
The one-shot installer already applies both equivalent patches automatically.
中文说明:一键安装脚本已经自动包含这两个补丁。
For the current workstation, `100.93.185.30` was also inserted directly into the
`domain` table to unblock user creation:
中文说明:当前工作站为了先让用户创建功能可用,已经把 `100.93.185.30` 直接写入 `domain` 表。
```sql
INSERT INTO domain (domain, attrs, accept_subdomain, last_modified)
SELECT '100.93.185.30', NULL, 0, NOW()
WHERE NOT EXISTS (SELECT 1 FROM domain WHERE domain='100.93.185.30');
```
The `domain` runtime module was enabled:
中文说明:同时启用了 OpenSIPS 的 `domain.so` 模块,并使用数据库模式。
```opensips
loadmodule "domain.so"
modparam("domain", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("domain", "db_mode", 1)
```
Validation:
```bash
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"domain_reload"}'
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"domain_dump"}'
```
Expected `domain_dump` output includes:
中文说明:期望 `domain_dump` 输出中包含当前服务器域名/IP。
```text
100.93.185.30
```
## Security notes
中文说明:安全注意事项。
- Keep MI HTTP bound to `127.0.0.1`.
- Do not expose `0.0.0.0:8888` to the network.
- Change the OpenSIPS-CP admin password.
- Use a stronger database password in production.
- Restrict SIP source IPs using `permissions` / `address` rules.
- Open RTP port range only where needed, for example `30000-40000/udp`.
## Runtime checks
中文说明:运行状态检查命令。
```bash
systemctl is-active mariadb apache2 opensips rtpengine-daemon
ss -ltnup | grep -E '(:80|:5060|:8888|:2223|:2812)'
curl -I http://127.0.0.1/cp/
curl -fsS -u admin:monit http://127.0.0.1:2812/ | grep -m1 Monit
curl -X POST http://127.0.0.1:8888/mi \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"ps"}'
```