coturn은 WebRTC 프로젝트에서 TURN/STUN 서버로 활용되는 오픈소스 소프트웨어이다. NAT와 방화벽을 넘어 사용자 간의 안정적인 통신을 지원하는 데 핵심적인 역할을 한다. 주로 WebRTC 기반의 영상 통화, 음성 통화, 그리고 P2P 데이터 전송 등에서 클라이언트 간의 연결 문제를 해결하는 데 활용된다.
Coturn은 WebRTC P2P 연결에서 NAT traversal(네트워크 주소 변환 문제 해결)을 도와준다. 5명 제한의 소규모 화상회의에서는 SFU(Selective Forwarding Unit)나 MCU(Multipoint Control Unit) 같은 복잡한 미디어 서버가 필요 없으므로, Coturn만으로 충분히 구현 가능하다. 따라서 OpenVidu 같은 복잡한 솔루션보다 쉽고 가벼우며, 소규모 트래픽에 최적화되어 효율적이다.
sudo apt update
sudo apt install coturn
우분투 서버 인스턴스에 다음과 같이 coturn을 설치해주었다.
coturn을 설치하고나면 /etc/turnserver.conf 경로로 설정 파일에 접근할 수 있다.
sudo vi /etc/turnserver.conf
설정 파일의 길이는 매우매우 길지만, 서버 테스트를 위해 실제로 변경한 값은 아래와 같다.
# TURN listener port for UDP and TCP (Default: 3478).
# Note: actually, TLS & DTLS sessions can connect to the
# "plain" TCP & UDP port(s), too - if allowed by configuration.
#
listening-port=3478
listening-port는 TURN 서버가 클라이언트의 요청을 수신할 포트 번호를 지정한다. 기본적으로 TURN 서버는 UDP와 TCP를 모두 3478 포트에서 수신한다.
# TURN listener port for TLS (Default: 5349).
# Note: actually, "plain" TCP & UDP sessions can connect to the TLS & DTLS
# port(s), too - if allowed by configuration. The TURN server
# "automatically" recognizes the type of traffic. Actually, two listening
# endpoints (the "plain" one and the "tls" one) are equivalent in terms of
# functionality; but Coturn keeps both endpoints to satisfy the RFC 5766 specs.
# For secure TCP connections, Coturn currently supports
# TLS version 1.0, 1.1 and 1.2.
# For secure UDP connections, Coturn supports DTLS version 1.
#
#tls-listening-port=5349
# Alternative listening port for UDP and TCP listeners;
# default (or zero) value means "listening port plus one".
# This is needed for RFC 5780 support
# (STUN extension specs, NAT behavior discovery). The TURN Server
# supports RFC 5780 only if it is started with more than one
# listening IP address of the same family (IPv4 or IPv6).
# RFC 5780 is supported only by UDP protocol, other protocols
# are listening to that endpoint only for "symmetry".
#
#alt-listening-port=0
# Alternative listening port for TLS and DTLS protocols.
# Default (or zero) value means "TLS listening port plus one".
#
#alt-tls-listening-port=0
listening-port 뿐만 아니라 TLS와 DTLS 프로토콜을 위한 설정도 다룰 수 있다. 실제로 변경한 값은 없지만, 추후 필요할 수도 있어서 정리해두자면,
tls-listening-portlistening-port)와 이 TLS 포트는 기능적으로 동등하지만, RFC 5766 규격을 만족하기 위해 둘 다 사용된다고 한다.alt-listening-portlistening-port + 1로 설정된다.alt-tls-listening-porttls-listening-port + 1로 설정된다.# Listener IP address of relay server. Multiple listeners can be specified.
# If no IP(s) specified in the config file or in the command line options,
# then all IPv4 and IPv6 system IPs will be used for listening.
#
#listening-ip=172.17.19.101
listening-ip=192.168.0.6
#listening-ip=10.207.21.238
#listening-ip=2607:f0d0:1002:51::4
listening-ip는 TURN 릴레이 서버가 어떤 IP 주소에서 클라이언트의 요청을 수신할지 정의할 수 있다. TURN 서버가 특정 네트워크 인터페이스에서만 요청을 수신하도록 제한하여, TURN 서버의 트래픽 관리를 할 수 있다. 여러 개의 listening-ip을 지정할 수 있으며, 각 IP 주소에 대해 서버가 리스닝하도록 설정할 수도 있다.
# For Amazon EC2 users:
#
# TURN Server public/private address mapping, if the server is behind NAT.
# In that situation, if a -X is used in form "-X <ip>" then that ip will be reported
# as relay IP address of all allocations. This scenario works only in a simple case
# when one single relay address is be used, and no RFC5780 functionality is required.
# That single relay address must be mapped by NAT to the 'external' IP.
# The "external-ip" value, if not empty, is returned in XOR-RELAYED-ADDRESS field.
# For that 'external' IP, NAT must forward ports directly (relayed port 12345
# must be always mapped to the same 'external' port 12345).
#
# In more complex case when more than one IP address is involved,
# that option must be used several times, each entry must
# have form "-X <public-ip/private-ip>", to map all involved addresses.
# RFC5780 NAT discovery STUN functionality will work correctly,
# if the addresses are mapped properly, even when the TURN server itself
# is behind A NAT.
#
# By default, this value is empty, and no address mapping is used.
#
#external-ip=60.70.80.91
#
#OR:
#
#external-ip=60.70.80.91/172.17.19.101
#external-ip=60.70.80.92/172.17.19.102
external-ip=223.130.155.54/192.168.0.6
external-ip는 Amazon EC2 같은 NAT 뒤에 있는 TURN 서버의 외부 IP와 내부 IP 주소 매핑을 정의한다. NAT 환경에서는 외부에서 접근 가능한 공인 IP와 내부 네트워크에서 사용되는 사설 IP가 다르기 때문에 이 설정이 필요하다.
TURN 서버가 클라이언트에게 자신의 릴레이 IP 주소를 보고할 때, 여기서 설정한 공인 IP가 XOR-RELAYED-ADDRESS 필드로 전송된다.
XOR-RELAYED-ADDRESS필드란?XOR-RELAYED-ADDRESS 필드는 TURN 서버가 자신의 릴레이 IP 주소를 클라이언트에게 전달하기 위해 사용되는 필드이다. 작동 방식 아래와 같다.
1. TURN 서버가 클라이언트의 요청을 처리하고, 클라이언트에게 할당된 릴레이 IP 주소를 계산한다.
2. TURN 서버는 이 IP 주소에 XOR 연산을 적용한 후, 응답 메세지 헤더의 XOR-RELAYED-ADDRESS 필드에 포함시켜 클라이언트에게 응답한다.
3. 클라이언트는 수신한 XOR 값을 해독하기 위해, 사전에 정의된 키를 사용하여 원래의 릴레이 IP 주소를 복원할 수 있다.
이로써 NAT 환경에서 TURN 서버를 사용하는 클라이언트가 서로 올바르게 연결될 수 있도록 보장할 수 있다.
# Lower and upper bounds of the UDP relay endpoints:
# (default values are 49152 and 65535)
#
min-port=49152
max-port=65535
min-port와 max-port는 TURN 서버가 클라이언트의 요청을 처리할 때 사용할 수 있는 UDP 포트의 최솟값과 최댓값을 설정한다. 클라이언트가 TURN 서버를 통해 다른 클라이언트와 통신할 때 사용된다.
verbose는 TURN 서버의 로그 출력을 조절하는 옵션이다. 기본적으로는 verbose 모드가 꺼져 있어서, TURN 서버는 최소한의 로그만 기록한다.
# Uncomment to run TURN server in 'normal' 'moderate' verbose mode.
# By default the verbose mode is off.
verbose
# Uncomment to run TURN server in 'extra' verbose mode.
# This mode is very annoying and produces lots of output.
# Not recommended under normal circumstances.
#
#Verbose
verbose 모드Verbose 모드 (대문자 V)production 환경에서는 로그를 최소화하여 시스템 리소스를 절약하는 것이 좋지만, 문제가 발생했을 때는 verbose 모드를 활성화하여 더 많은 정보를 얻는 것이 좋다.
TURN 서버에서 사용자 인증 및 보안 관련 기능을 조정하는 옵션이다.
# Uncomment to use fingerprints in the TURN messages.
# By default the fingerprints are off.
#
fingerprint
# Uncomment to use long-term credential mechanism.
# By default no credentials mechanism is used (any user allowed).
#
lt-cred-mech
# This option is the opposite of lt-cred-mech.
# (TURN Server with no-auth option allows anonymous access).
# If neither option is defined, and no users are defined,
# then no-auth is default. If at least one user is defined,
# in this file, in command line or in usersdb file, then
# lt-cred-mech is default.
#
#no-auth
fingerprintlt-cred-mechLT-cred-mech는 사용자 인증을 위한 장기적인 자격 증명을 사용하여 보안을 강화한다. 사용자가 TURN 서버에 접근할 때 사용자 이름과 비밀번호를 요구한다.lt-cred-mech 옵션이 주석 처리되어 있을 경우, 기본적으로 TURN 서버는 인증 메커니즘을 사용하지 않으며 모든 사용자가 접근할 수 있다.no-authuser 관련 설정에서 LT-cred-mech에 대한 사용자 이름과 비밀번호를 설정한다.
# 'Static' user accounts for the long term credentials mechanism, only.
# This option cannot be used with TURN REST API.
# 'Static' user accounts are NOT dynamically checked by the turnserver process,
# so they can NOT be changed while the turnserver is running.
#
#user=username1:key1
#user=username2:key2
# OR:
#user=username1:password1
#user=username2:password2
user=booskit:<비밀번호>
정적 사용자 계정은 TURN 서버에서 사용할 수 있는 사용자 계정으로, 사용자의 인증 정보를 서버의 구성 파일에 미리 정의한다. 정적 사용자 계정은 TURN 서버가 실행 중일 때 동적으로 변경할 수 없으며, 변경하려면 서버를 재시작해야 한다.
TURN REST API는 정적 사용자 계정과 함께 사용할 수 없다. TURN REST API를 사용하는 경우에는 동적 사용자 관리가 필요하다. 따라서 REST API를 사용하려면 Coturn 설정 파일에서 REST API 관련 옵션을 활성화해야한다.
| 정적 사용자 계정 | 동적 사용자 계정 | |
|---|---|---|
| 계정 주인 | 서비스 관리자 또는 개발자 | 서비스 이용 고객의 계정 (WebRTC 클라이언트) |
| 계정 정보 관리 | turnserver.conf 파일에서 미리 정의 | HTTP POST 요청을 /api/users 에 전송하여 사용자를 추가하거나 삭제(요청 본문에 사용자 이름과 비밀번호를 포함) |
| 서버 실행 중에 계정 변경 가능 유무 | 불가능 | 가능 |
realm은 사용자가 TURN 서버에 연결할 때 인증을 위한 범위를 정의하는 값이다. 여기서 사용자는 정적 사용자와 동적 사용자 둘 다를 의미한다.
# The default realm to be used for the users when no explicit
# origin/realm relationship is found in the database, or if the TURN
# server is not using any database (just the commands-line settings
# and the userdb file). Must be used with long-term credentials
# mechanism or with TURN REST API.
#
# Note: If the default realm is not specified, then realm falls back to the host domain name.
# If the domain name string is empty, or set to '(None)', then it is initialized as an empty string.
#
realm=boostcamp-preview.kro.kr
사용자가 TURN 서버에 연결할 때 이 realm 값이 인증 프로세스에서 사용된다. 즉, 사용자가 로그인할 때 username:password 형태의 자격 증명과 함께 이 realm이 포함되어야 한다. 사용자가 특정 realm에 대한 자격 증명을 제공해야만 서버에 접근할 수 있기 때문에 realm을 적절히 설정하는 것이 중요하다.
이제 설정 파일의 내용에 맞춰 클라우드 보안 그룹을 구성해야 한다. UDP와 TCP의 3478 포트를 열어주면 된다. 만약 TLS를 사용한다면 5349 포트도 열어줘야 한다.
서버가 새로 시작될 때마다 coturn 서버도 자동으로 실행되도록 설정해줄 수 있다. 이번에는 이전에 봤던 설정 파일이 아니라 아래의 경로의 파일에서 해줘야한다.
sudo vi /etc/default/coturn
해당 파일은 coturn 서비스의 실행과 관련된 환경 설정을 담당한다.
# Uncomment it if you want to have the turnserver running as
# an automatic system service daemon
#
TURNSERVER_ENABLED=1
위와 같이 주석을 해제해주면 시스템이 시작될 때마다 coturn 서버도 자동으로 실행된다.