본 가이드에서는 Ubuntu 24.x 환경에서 Asterisk 설치부터 pjsip.conf, extensions.conf 설정, 그리고 안드로이드 Linphone을 이용한 테스트까지 VoIP 시스템 구축 전 과정을 안내합니다.

Asterisk 설치 및 기본 설정

sudo apt update
sudo apt install asterisk
sudo systemctl start asterisk
sudo systemctl enable asterisk

소스 설치

Asterisk 소스 코드를 다운로드합니다.

sudo apt install wget build-essential subversion
cd /usr/src/
sudo wget https://github.com/asterisk/asterisk/releases/download/21.3.1/asterisk-21.3.1.tar.gz
sudo tar zxvf asterisk-21.3.1.tar.gz
sudo rm asterisk-21.3.1.tar.gz
cd asterisk-21.3.1

sudo contrib/scripts/get_mp3_source.sh
sudo contrib/scripts/install_prereq install
sudo ./configure

sudo make menuselect # "format_mp3" 옵션을 선택
sudo make -j2
sudo make install
sudo make samples
sudo make basic-pbx
sudo make config
sudo ldconfig
sudo adduser --system --group --home /var/lib/asterisk --no-create-home --gecos "Asterisk PBX" asterisk
sudo vi /etc/default/asterisk

# /etc/default/asterisk

AST_USER="asterisk"
AST_GROUP="asterisk"

사용자 추가

sudo usermod -a -G dialout,audio asterisk

사용자 권한 설정

sudo chown -R asterisk: /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk
sudo chmod -R 750 /var/{lib,log,run,spool}/asterisk /usr/lib/asterisk /etc/asterisk

필요에 따라 방화벽 포트(5060/udp, 5061/tcp)를 열어줍니다.

STUN 서버 설치 (optional)

coturn은 오픈 소스 TURN (Traversal Using Relay NAT)STUN (Session Traversal Utilities for NAT) 서버입니다. 쉽게 말해, NAT(Network Address Translation) 환경에서 P2P(Peer-to-Peer) 통신을 가능하게 해주는 서버 소프트웨어입니다. 필요시 Asterisk와 같이 사용할 필요가 있습니다.

coturn 설치

sudo apt-get update
sudo apt-get install coturn

/etc/turnserver.conf 파일을 편집합니다.

listening-port=3478
tls-listening-port=5349
# 외부 IP 주소 설정 (공유기 사용 시 WAN IP)
external-ip=YOUR_PUBLIC_IP
# 로그 활성화
verbose
fingerprint
lt-cred-mech

# 인증 정보 설정 (realm, username, password)
realm=YOUR_REALM
user=YOUR_USERNAME:YOUR_PASSWORD

coturn 실행

sudo systemctl start coturn
sudo systemctl enable coturn

필요한 포트(UDP/TCP 3478, 5349)를 열어줍니다.

sudo ufw allow 3478/udp
sudo ufw allow 3478/tcp
sudo ufw allow 5349/udp
sudo ufw allow 5349/tcp

pjsip.conf 설정

701~703번 내선에 대한 설정을 추가했습니다.

[701]
type=aor
max_contacts=1
contact=sip:701@:5060

[701]
type=auth
auth_type=userpass
username=701
password=

[701]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw,alaw
aors=701
auth=701
subscribe_context=state-hints
rtp_symmetric=yes
force_rport=yes

[701]
type=registration
transport=transport-udp
outbound_auth=701
server_uri=sip::5060
client_uri=sip:701@:5060
retry_interval=60
max_retries=10

[702]
type=aor
max_contacts=1
contact=sip:702@:5060

[702]
type=auth
auth_type=userpass
username=702
password=

[702]
type=endpoint
transport=transport-udp
context=default
disallow=all
allow=ulaw,alaw
aors=702
auth=702
subscribe_context=state-hints
rtp_symmetric=yes
force_rport=yes

[702]
type=registration
transport=transport-udp
outbound_auth=702
server_uri=sip::5060
client_uri=sip:702@:5060
retry_interval=60
max_retries=10

위 설정은 Asterisk PBX 시스템의 pjsip.conf 파일 내용으로, 701, 702, 703번 내선을 설정하고 등록하는 방법을 보여줍니다. 각 내선은 동일한 형식으로 설정되며, 몇 가지 핵심 구성 요소로 이루어집니다.

  1. AOR (Address of Record):
    • type=aor : AOR 객체를 정의합니다.
    • max_contacts=1 : 최대 연락처 수를 제한합니다.
    • contact=sip:70x@:5060 : 해당 내선의 SIP 주소를 지정합니다. 는 공인 IP 주소로 변경해야 합니다.
  2. Auth (Authentication):
    • type=auth : 인증 객체를 정의합니다.
    • auth_type=userpass : 사용자 이름/비밀번호 인증 방식을 사용합니다.
    • username=70x : 내선 번호와 동일한 사용자 이름을 설정합니다.
    • password= : 해당 내선의 비밀번호를 설정합니다. 는 실제 비밀번호로 변경해야 합니다.
  3. Endpoint:
    • type=endpoint : 엔드포인트 객체를 정의합니다.
    • transport=transport-udp : UDP 전송 프로토콜을 사용합니다.
    • context=default : 기본 다이얼 플랜 컨텍스트를 사용합니다.
    • disallow=all : 모든 코덱을 기본적으로 비활성화합니다.
    • allow=ulaw,alaw : ulaw 및 alaw 코덱만 허용합니다.
    • aors=70x : 해당 내선의 AOR를 연결합니다.
    • auth=70x : 해당 내선의 인증 정보를 연결합니다.
    • subscribe_context=state-hints : 상태 정보 구독을 위한 컨텍스트를 설정합니다.
    • rtp_symmetric=yes : RTP 대칭을 활성화합니다.
    • force_rport=yes : RTP 미디어 스트림에 대해 원격 포트를 강제로 사용합니다.
  4. Registration:
    • type=registration : 등록 객체를 정의합니다.
    • transport=transport-udp : UDP 전송 프로토콜을 사용합니다.
    • outbound_auth=70x : 아웃바운드 인증에 해당 내선의 인증 정보를 사용합니다.
    • server_uri=sip::5060 : 등록할 SIP 서버의 URI를 지정합니다.
    • client_uri=sip:70x@:5060 : 내선의 클라이언트 URI를 지정합니다. 는 사설 IP 주소로 변경해야 합니다.
    • retry_interval=60 : 등록 재시도 간격을 60초로 설정합니다.
    • max_retries=10 : 최대 등록 재시도 횟수를 10회로 설정합니다.

위 설정은 기본적인 내선 설정이며, 필요에 따라 다양한 옵션을 추가하거나 수정할 수 있습니다. 는 실제 IP 주소로 변경해야 하며, ``는 강력한 비밀번호로 설정하는 것이 좋습니다. 추가적인 내선을 설정하려면 701, 702, 703번 부분을 원하는 내선 번호로 변경하고 해당 설정을 복사하여 추가하면 됩니다.

extensions.conf 설정

extensions.conf 설정은 각 내선 번호로 전화가 오면 해당 내선으로 연결하고, 연결되지 않을 경우 음성 메일로 연결하는 다이얼 플랜입니다.

[default]
exten => 701,1,NoOp(Calling 701)
 same => n,Dial(PJSIP/701,20)
 same => n,VoiceMail(701@default,u)
 same => n,Hangup()

exten => 702,1,NoOp(Calling 702)
 ... (생략)

exten => 703,1,NoOp(Calling 703)
 ... (생략)

conf 생성 스크립트 (optional)

1000번부터 2000번까지 채널을 설정하는 스크립트

#!/bin/bash

# 설정 값
START_EXTENSION=1000
END_EXTENSION=2000
EXTERNAL_SIGNALING_ADDRESS="YOUR_PUBLIC_IP"
LOCAL_IP_ADDRESS="YOUR_PRIVATE_IP"
MAX_CONTACTS=5
PASSWORD=PASSWORD
STUN_SERVER="YOUR_PUBLIC_IP:5349"

# sip.conf 파일 초기화 (선택 사항)
echo "" > /etc/asterisk/pjsip.conf

# 기본 설정 추가
cat <<EOF >> /etc/asterisk/pjsip.conf
[general]
;context=default
;bindport=5060
;bindaddr=0.0.0.0
;rtpstart=10000
;rtpend=20000
;disallow=all
;allow=ulaw,alaw
;externip=$EXTERNAL_SIGNALING_ADDRESS
;nat=force_rport,comedia
;disallow=all
;allow=ulaw,alaw,g722

[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
;ice_support=yes
;local_net=$LOCAL_IP_ADDRESS/24
;external_signaling_address=$EXTERNAL_SIGNALING_ADDRESS
;external_media_address=$EXTERNAL_SIGNALING_ADDRESS

[transport-tcp]
type=transport
protocol=tcp
bind=0.0.0.0

EOF

# 채널 설정 반복 생성
for (( extension=$START_EXTENSION; extension<=$END_EXTENSION; extension++ )); do
cat <<EOF >> /etc/asterisk/pjsip.conf
[$extension]
type=aor
max_contacts=$MAX_CONTACTS
contact=sip:$extension@$EXTERNAL_SIGNALING_ADDRESS:5060

[$extension]
type=auth
auth_type=userpass
username=$extension
password=$PASSWORD

[$extension]
type=endpoint
transport=transport-udp
context=default
dtmf_mode=rfc4733
disallow=all
allow=ulaw
allow=alaw
allow=h264
ice_support=yes
;direct_media=no
force_rport=yes
rtp_symmetric=yes
;rewrite_contact=yes
aors=$extension
auth=$extension
;subscribe_context=state-hints

;[$extension]
;type=endpoint
;transport=transport-udp
;context=default
;disallow=all
;allow=ulaw,alaw
;aors=$extension
;auth=$extension
;media_encryption=sdes
;ice_support=yes
;use_avpf=yes
;media_use_received_transport=yes
;rtcp_mux=yes

;[$extension]
;type=identify
;endpoint=$extension
;match=$EXTERNAL_SIGNALING_ADDRESS

[$extension]
type=registration
transport=transport-udp
outbound_auth=$extension
server_uri=sip:$EXTERNAL_SIGNALING_ADDRESS:5060
client_uri=sip:$extension@$LOCAL_IP_ADDRESS:5060
retry_interval=60
max_retries=10

EOF
done

rm /var/lib/asterisk/astdb.sqlite3 # 활성 채널, 등록된 사용자 제거
service asterisk restart # 재시작

방화벽 오픈

Asterisk에 관련된 방화벽 규칙만 설명드리겠습니다. Asterisk와 관련된 포트는 주로 SIP 트래픽 및 RTP 트래픽을 처리하는 포트들입니다.

  1. UDP 포트 5060
    • IP 주소: 0.0.0.0/0
    • 설명: 모든 IP 주소에서 UDP 포트 5060으로의 접근을 허용합니다. 이 포트는 일반적으로 SIP 트래픽을 처리하는 데 사용됩니다.
  2. TCP 포트 5060 - 5061
    • IP 주소: 0.0.0.0/0
    • 설명: 모든 IP 주소에서 TCP 포트 5060에서 5061로의 접근을 허용합니다. 이 포트들은 SIP 트래픽을 처리하는 데 사용됩니다.
  3. UDP 포트 10000 - 20000
    • IP 주소: 0.0.0.0/0
    • 설명: 모든 IP 주소에서 UDP 포트 10000에서 20000로의 접근을 허용합니다. 이 포트 범위는 RTP 트래픽을 처리하는 데 주로 사용됩니다.

이 설정들은 Asterisk 서버가 외부에서 들어오는 SIP 요청과 RTP 미디어 스트림을 처리할 수 있도록 합니다. SIP 포트(5060)와 RTP 포트(10000-20000)는 VoIP 통신을 위해 필수적입니다.

안드로이드 Linphone을 이용한 테스트

  1. Linphone 설치: 구글 플레이 스토어에서 Linphone 앱을 설치합니다.
  2. 계정 설정: Linphone 앱에서 새로운 SIP 계정을 생성합니다.
    • 사용자 이름: pjsip.conf에 설정된 내선 번호 (예: 701)
    • 비밀번호: pjsip.conf에 설정된 비밀번호
    • 도메인: Asterisk 서버의 IP 주소 또는 도메인 이름
  3. 통화 테스트: 다른 내선 번호로 전화를 걸거나 받아서 통화 품질을 테스트합니다.

추가 설정 및 고려 사항

  • NAT 환경: NAT 환경에서는 pjsip.confextern_host, extern_refresh, direct_media 등의 옵션을 추가로 설정해야 할 수 있습니다.
  • 보안: TLS 암호화 통신을 설정하고, 강력한 사용자 이름과 비밀번호를 사용하여 보안을 강화합니다.
  • 고급 기능: 착신 전환, 통화 녹음, IVR (Interactive Voice Response) 등 다양한 기능을 추가하여 Asterisk 시스템을 확장할 수 있습니다.
  • Linphone 문제 해결: Linphone에서 오디오 코덱 문제가 발생할 경우, pjsip.confallow 항목을 확인하고 Linphone의 설정에서도 동일한 코덱을 활성화해야 합니다.