Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ MONGODB_PORT_NUMBER=27017
# Nats
NATS_PORT_NUMBER=4222
NATS_BIND_IP=127.0.0.1

# SIP
VOIP_DOMAIN=valid.voip.domain.com
FREESWITCH_PASSWORD=admin_1234
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,4 +136,16 @@ When running multiple Rocket.Chat servers, you can configure Traefik to discover
```env
ROCKETCHAT_BACKEND_SERVERS=rocketchat-1:3000,rocketchat-2:3000,rocketchat-3:3000
```

### VoIP setup
There is a quick way for rolling out a VoIP solution using Drachtio and FreeSwitch as a SIP proxy. To achieve this some network configurations are required. `compose.network.yml` defines a network private network called `rc_voip_private` for VoIP servers. Currently it uses subnet 172.28.0.0/16 and assigns static IP 172.28.0.10 and 172.28.0.11. If you would want to change this network configuration, add desired value for subnet and static ip addresses in that subnet to `freeswitch` and `drachtio` service. `compose.network.yml` also configures rocketchat service to have access to default and `rc_voip_private` network. It communicates with non VoIP services on default network and VoIP services on `rc_voip_private` network. Once the desired configuration changes are made, run
```bash
docker compose \
-f compose.monitoring.yml \
-f compose.traefik.yml \
-f compose.database.yml \
-f compose.yml \
-f compose.voip.yml \
-f compose.network.yml \
up -d
```
to start the stack. Once the stack is running, do the necessary VoIP configurations using the static ips for FreeSwitch and Drachtio.
29 changes: 29 additions & 0 deletions compose.voip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
services:
freeswitch:
image: docker.io/rocketchat/freeswitch:latest
# build: .
restart: always
environment:
EXTERNAL_ADDRESS_FQDN: ${VOIP_DOMAIN:-}
FREESWITCH_PASSWORD: ${FREESWITCH_PASSWORD:-}
RTP_START_PORT: 20000
RTP_END_PORT: 20046
Comment on lines +9 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should allow customizing these ports via envvars on the .env file as well? Though we would need to set the same values on the port list as well.

I'm also not 100% sure if those should be the default values for those ports. This default list limits FS to 23 concurrent calls, which might be too small a number for production envs. We were using those values up to now because EKS has a limit of 50 open ports.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Could we do this in the next iteration when we have a basic stack building repo ready? Ideally I dont want to compose this file here but instead, link it to the one from here i.e the VoiP server image repo. Please let me know once you push your PR #52. Then I can work on adding a reference instead of copying the file.

DEBUG_MODE: "true"
ACCEPT_EXTERNAL_CALLS: false
USE_LEGACY_ARCH: false
DRACHTIO_DOMAIN: ${VOIP_DRACHTIO_DOMAIN:-drachtio}
expose:
- 5060
ports:
- 20000-20046:20000-20046/udp

drachtio:
image: drachtio/drachtio-server:latest
restart: always
ports:
- "9022:9022"
- "5060:5060/udp"
volumes:
# Drachtio params are configured on this file
# You must modify it to configure a strong and unique secret string
- ./files/drachtio/drachtio.conf.xml:/etc/drachtio.conf.xml
200 changes: 200 additions & 0 deletions files/drachtio/drachtio.conf.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
<drachtio>

<!-- udp port to listen on for client connections (default 9022), and shared secret used to authenticate clients -->
<admin port="9022" secret="set a strong secret here">0.0.0.0</admin>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be best if we could configure drachtio without needing to change this file directly.

I'll check what our options are and try to make something to avoid this.


<!-- the server can either accept inbound connections from node apps, or make outbound requests
to node apps. You must globally choose one or the other approach but not both.

Inbound connections requires no configuration other than the <admin/> tag above, and are useful
when a server is hosting a single application, or has one primary function.

If, on the other hand, you want a server to support multiple applications, then we have the issue
of determining how to route an incoming request (INVITE, REGISTER, etc) to the appropriate application.
This is what outbound connections are designed for.

By uncommenting the <request-handlers/> configuration below, you are placing the server into outbound mode, and
providing an HTTP URL that the server will hit to determine how to route an incoming request.
The following parameters will be passed to the http service as query string parameters in an HTTP GET:

callingNumber - the user part of the From header
calledNumber - the user part of the To header
contentType - the Content-Type header (if any)
domain - the domain in the request uri
method - the sip method
protocol - the transport protocol
source_address - the sending address
uriUser - the user part of the sip uri
uri - the complete sip uri

It is the responsibility of the HTTP server that receives the request to return a json response
with a top-level "action" of either "reject", "redirect", "proxy", or "route".

reject - reject the call with a specified status code
redirect = redirect the call to one or more specified sip uris
proxy - proxy the call to one or more specified sip uris
route - connect to a nodejs application that is listening on the specified host:port

example responses:

{
"action": "reject":
"data": {
"status": 503,
"reason": "Max Calls Exceeded"
}
}

{
"action": "redirect":
"data": {
"contacts": [
"sip:foo@bar.com"
]
}
}

{
"action": "proxy":
"data": {
"destination": [
"sip:foo@bar.com"
],
recordRoute: true
}
}

{
"action": "route":
"data": {
"url": "call-recording.default.svc.cluster.local:4000"
}
}

{
"action": "route":
"data": {
"tag": "my-conferencing-app"
}
}

-->

<!-- comment this in and edit http url to use outbound connections
Note: currently only HTTP GET is supported as an HTTP METHOD
<request-handlers>
<request-handler sip-method="INVITE" http-method="GET">http://35.187.89.96:80</request-handler>
</request-handlers>
-->
<!-- sip configuration -->
<sip>
<contacts>
<!-- <contact>sip:*;transport=tcp</contact> -->
<contact>sip:*;transport=udp</contact>
<!-- local sip address to bind to. Default: 'sip:*', which means listens on port 5060 on all interfaces and transports -->
<!--
Other examples:
sip:192.168.1.100 listen on a specific address
sip:*;transport=tcp tcp connections only
sip:*:5061 listen on port 5061
-->


<!-- here's how to listen for every protocol on their default ports -->
<!--
<contact>sip:*:80;transport=ws</contact>
<contact>sips:*;transport=tls</contact>
<contact>sips:*:443;transport=wss</contact>
-->

</contacts>

<!-- uncomment and modify these if you want to change the sip stack timers (globally)
<timers>
<t1>500</t1>
<t2>4000</t2>
<t4>5000</t4>
<t1x64>32000</t1x64>
</timers>
-->

<!-- uncomment this if you send encapsulated SIP messages to homer
<capture-server port="9060" hep-version="3" id="101">127.0.0.1</capture-server>
-->

<!-- if you want to terminate SIP over TLS connections (example shows letsencrypt.org typical file locations, but use any CA)
<tls>
<key-file>/etc/letsencrypt/live/yourdomain/privkey.pem</key-file>
<cert-file>/etc/letsencrypt/live/yourdomain/cert.pem</cert-file>
<chain-file>/etc/letsencrypt/live/yourdomain/chain.pem</chain-file>
<dh-param>/var/local/dh4096.pem</dh-param>
</tls>
-->

<!-- if you want to increase the default mtu size for udp packets; stack will force tcp when sending larger packets
<mtu-size>4096</mtu-size>
-->
<udp-mtu>8192</udp-mtu>

<!-- uncommenting this will cause all outbound new requests (i.e. requests outside of a dialog) to go through the specified proxy -->
<!--
<outbound-proxy>sip:10.10.10.1</outbound-proxy>
-->

<!-- optional list of header values which, if encountered in a message will trigger an action
[tcp-]action="reject|discard"
reject means send a sip non-success response immediately
discard means sliently discard the request, generating no response
-->
<spammers action="reject" tcp-action="discard">
<header name="User-Agent">
<value>sip-cli</value>
<value>sipcli</value>
<value>friendly-scanner</value>
</header>
<header name="To">
<value>sipvicious</value>
</header>
</spammers>
</sip>

<!-- set to true if you want the server to cdr events to a connected client -->
<cdrs>false</cdrs>

<monitoring>
<prometheus port="8088">127.0.0.1</prometheus>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also be configured to work with the prometheus configured on the existing compose.monitoring.yaml

</monitoring>

<!-- logging configuration -->
<logging>

<!-- uncomment this if you want logging dumped to console, in addition to any other log destinations
-->
<console/>

<!-- uncomment if you want logging sent to syslog (over UDP) -->
<!--
<syslog>
<address>my.syslog.serve</address>
<port>514</port>
<facility>local6</facility>
</syslog>
-->

<!-- file-based logging -->
<file>
<name>/var/log/drachtio/drachtio.log</name>
<archive>/var/log/drachtio/archive</archive>
<size>100</size>
<maxFiles>20</maxFiles>
<auto-flush>true</auto-flush>
</file>

<!-- sofia (internal sip library) log level, from 0 (minimal) to 9 (verbose) -->
<sofia-loglevel>3</sofia-loglevel>

<!-- general process log level: notice, warning, error, info, debug. Default: info -->
<loglevel>info</loglevel>
</logging>

</drachtio>