mirror of
https://github.com/chatmail/relay.git
synced 2026-05-10 16:04:37 +00:00
feat: setup TURN server
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## untagged
|
## untagged
|
||||||
|
|
||||||
|
- Setup TURN server
|
||||||
|
([#621](https://github.com/chatmail/relay/pull/621))
|
||||||
|
|
||||||
- Update iroh-relay to 0.35.0
|
- Update iroh-relay to 0.35.0
|
||||||
([#650](https://github.com/chatmail/relay/pull/650))
|
([#650](https://github.com/chatmail/relay/pull/650))
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ echobot = "chatmaild.echo:main"
|
|||||||
chatmail-metrics = "chatmaild.metrics:main"
|
chatmail-metrics = "chatmaild.metrics:main"
|
||||||
delete_inactive_users = "chatmaild.delete_inactive_users:main"
|
delete_inactive_users = "chatmaild.delete_inactive_users:main"
|
||||||
lastlogin = "chatmaild.lastlogin:main"
|
lastlogin = "chatmaild.lastlogin:main"
|
||||||
|
turnserver = "chatmaild.turnserver:main"
|
||||||
|
|
||||||
[project.entry-points.pytest11]
|
[project.entry-points.pytest11]
|
||||||
"chatmaild.testplugin" = "chatmaild.tests.plugin"
|
"chatmaild.testplugin" = "chatmaild.tests.plugin"
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ from .config import read_config
|
|||||||
from .dictproxy import DictProxy
|
from .dictproxy import DictProxy
|
||||||
from .filedict import FileDict
|
from .filedict import FileDict
|
||||||
from .notifier import Notifier
|
from .notifier import Notifier
|
||||||
|
from .turnserver import turn_credentials
|
||||||
|
|
||||||
|
|
||||||
def _is_valid_token_timestamp(timestamp, now):
|
def _is_valid_token_timestamp(timestamp, now):
|
||||||
@@ -75,11 +76,12 @@ class Metadata:
|
|||||||
|
|
||||||
|
|
||||||
class MetadataDictProxy(DictProxy):
|
class MetadataDictProxy(DictProxy):
|
||||||
def __init__(self, notifier, metadata, iroh_relay=None):
|
def __init__(self, notifier, metadata, iroh_relay=None, turn_hostname=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.notifier = notifier
|
self.notifier = notifier
|
||||||
self.metadata = metadata
|
self.metadata = metadata
|
||||||
self.iroh_relay = iroh_relay
|
self.iroh_relay = iroh_relay
|
||||||
|
self.turn_hostname = turn_hostname
|
||||||
|
|
||||||
def handle_lookup(self, parts):
|
def handle_lookup(self, parts):
|
||||||
# Lpriv/43f5f508a7ea0366dff30200c15250e3/devicetoken\tlkj123poi@c2.testrun.org
|
# Lpriv/43f5f508a7ea0366dff30200c15250e3/devicetoken\tlkj123poi@c2.testrun.org
|
||||||
@@ -98,6 +100,11 @@ class MetadataDictProxy(DictProxy):
|
|||||||
):
|
):
|
||||||
# Handle `GETMETADATA "" /shared/vendor/deltachat/irohrelay`
|
# Handle `GETMETADATA "" /shared/vendor/deltachat/irohrelay`
|
||||||
return f"O{self.iroh_relay}\n"
|
return f"O{self.iroh_relay}\n"
|
||||||
|
elif keyname == "vendor/vendor.dovecot/pvt/server/vendor/deltachat/turn":
|
||||||
|
res = turn_credentials()
|
||||||
|
port = 3478
|
||||||
|
return f"O{self.turn_hostname}:{port}:{res}\n"
|
||||||
|
|
||||||
logging.warning(f"lookup ignored: {parts!r}")
|
logging.warning(f"lookup ignored: {parts!r}")
|
||||||
return "N\n"
|
return "N\n"
|
||||||
|
|
||||||
@@ -121,6 +128,7 @@ def main():
|
|||||||
|
|
||||||
config = read_config(config_path)
|
config = read_config(config_path)
|
||||||
iroh_relay = config.iroh_relay
|
iroh_relay = config.iroh_relay
|
||||||
|
mail_domain = config.mail_domain
|
||||||
|
|
||||||
vmail_dir = config.mailboxes_dir
|
vmail_dir = config.mailboxes_dir
|
||||||
if not vmail_dir.exists():
|
if not vmail_dir.exists():
|
||||||
@@ -134,7 +142,10 @@ def main():
|
|||||||
notifier.start_notification_threads(metadata.remove_token_from_addr)
|
notifier.start_notification_threads(metadata.remove_token_from_addr)
|
||||||
|
|
||||||
dictproxy = MetadataDictProxy(
|
dictproxy = MetadataDictProxy(
|
||||||
notifier=notifier, metadata=metadata, iroh_relay=iroh_relay
|
notifier=notifier,
|
||||||
|
metadata=metadata,
|
||||||
|
iroh_relay=iroh_relay,
|
||||||
|
turn_hostname=mail_domain,
|
||||||
)
|
)
|
||||||
|
|
||||||
dictproxy.serve_forever_from_socket(socket)
|
dictproxy.serve_forever_from_socket(socket)
|
||||||
|
|||||||
9
chatmaild/src/chatmaild/turnserver.py
Normal file
9
chatmaild/src/chatmaild/turnserver.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
|
def turn_credentials() -> str:
|
||||||
|
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client_socket:
|
||||||
|
client_socket.connect("/run/chatmail-turn/turn.socket")
|
||||||
|
with client_socket.makefile("rb") as file:
|
||||||
|
return file.readline().decode("utf-8")
|
||||||
@@ -128,6 +128,7 @@ def _install_remote_venv_with_chatmaild(config) -> None:
|
|||||||
"echobot",
|
"echobot",
|
||||||
"chatmail-metadata",
|
"chatmail-metadata",
|
||||||
"lastlogin",
|
"lastlogin",
|
||||||
|
"turnserver",
|
||||||
):
|
):
|
||||||
execpath = fn if fn != "filtermail-incoming" else "filtermail"
|
execpath = fn if fn != "filtermail-incoming" else "filtermail"
|
||||||
params = dict(
|
params = dict(
|
||||||
@@ -497,6 +498,56 @@ def check_config(config):
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def deploy_turn_server(config):
|
||||||
|
(url, sha256sum) = {
|
||||||
|
"x86_64": (
|
||||||
|
"https://github.com/chatmail/chatmail-turn/releases/download/v0.3/chatmail-turn-x86_64-linux",
|
||||||
|
"841e527c15fdc2940b0469e206188ea8f0af48533be12ecb8098520f813d41e4",
|
||||||
|
),
|
||||||
|
"aarch64": (
|
||||||
|
"https://github.com/chatmail/chatmail-turn/releases/download/v0.3/chatmail-turn-aarch64-linux",
|
||||||
|
"a5fc2d06d937b56a34e098d2cd72a82d3e89967518d159bf246dc69b65e81b42",
|
||||||
|
),
|
||||||
|
}[host.get_fact(facts.server.Arch)]
|
||||||
|
|
||||||
|
need_restart = False
|
||||||
|
|
||||||
|
existing_sha256sum = host.get_fact(Sha256File, "/usr/local/bin/chatmail-turn")
|
||||||
|
if existing_sha256sum != sha256sum:
|
||||||
|
server.shell(
|
||||||
|
name="Download chatmail-turn",
|
||||||
|
commands=[
|
||||||
|
f"(curl -L {url} >/usr/local/bin/chatmail-turn.new && (echo '{sha256sum} /usr/local/bin/chatmail-turn.new' | sha256sum -c) && mv /usr/local/bin/chatmail-turn.new /usr/local/bin/chatmail-turn)",
|
||||||
|
"chmod 755 /usr/local/bin/chatmail-turn",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
need_restart = True
|
||||||
|
|
||||||
|
source_path = importlib.resources.files(__package__).joinpath(
|
||||||
|
"service", "turnserver.service.f"
|
||||||
|
)
|
||||||
|
content = source_path.read_text().format(mail_domain=config.mail_domain).encode()
|
||||||
|
|
||||||
|
systemd_unit = files.put(
|
||||||
|
name="Upload turnserver.service",
|
||||||
|
src=io.BytesIO(content),
|
||||||
|
dest="/etc/systemd/system/turnserver.service",
|
||||||
|
user="root",
|
||||||
|
group="root",
|
||||||
|
mode="644",
|
||||||
|
)
|
||||||
|
need_restart |= systemd_unit.changed
|
||||||
|
|
||||||
|
systemd.service(
|
||||||
|
name="Setup turnserver service",
|
||||||
|
service="turnserver.service",
|
||||||
|
running=True,
|
||||||
|
enabled=True,
|
||||||
|
restarted=need_restart,
|
||||||
|
daemon_reload=systemd_unit.changed,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def deploy_mtail(config):
|
def deploy_mtail(config):
|
||||||
# Uninstall mtail package, we are going to install a static binary.
|
# Uninstall mtail package, we are going to install a static binary.
|
||||||
apt.packages(name="Uninstall mtail", packages=["mtail"], present=False)
|
apt.packages(name="Uninstall mtail", packages=["mtail"], present=False)
|
||||||
@@ -673,6 +724,8 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
|
|||||||
packages=["rsync"],
|
packages=["rsync"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
deploy_turn_server(config)
|
||||||
|
|
||||||
# Run local DNS resolver `unbound`.
|
# Run local DNS resolver `unbound`.
|
||||||
# `resolvconf` takes care of setting up /etc/resolv.conf
|
# `resolvconf` takes care of setting up /etc/resolv.conf
|
||||||
# to use 127.0.0.1 as the resolver.
|
# to use 127.0.0.1 as the resolver.
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
enable_relay = true
|
enable_relay = true
|
||||||
http_bind_addr = "[::]:3340"
|
http_bind_addr = "[::]:3340"
|
||||||
enable_stun = true
|
|
||||||
|
# Disable built-in STUN server in iroh-relay 0.35
|
||||||
|
# as we deploy our own TURN server instead.
|
||||||
|
# STUN server is going to be removed in iroh-relay 1.0
|
||||||
|
# and this line can be removed after upgrade.
|
||||||
|
enable_stun = false
|
||||||
|
|
||||||
enable_metrics = false
|
enable_metrics = false
|
||||||
metrics_bind_addr = "127.0.0.1:9092"
|
metrics_bind_addr = "127.0.0.1:9092"
|
||||||
|
|||||||
16
cmdeploy/src/cmdeploy/service/turnserver.service.f
Normal file
16
cmdeploy/src/cmdeploy/service/turnserver.service.f
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=A wrapper for the TURN server
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Restart=always
|
||||||
|
ExecStart=/usr/local/bin/chatmail-turn --realm {mail_domain} --socket /run/chatmail-turn/turn.socket
|
||||||
|
|
||||||
|
# Create /run/chatmail-turn
|
||||||
|
RuntimeDirectory=chatmail-turn
|
||||||
|
User=vmail
|
||||||
|
Group=vmail
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
Reference in New Issue
Block a user