SIPサーバFlexisipのTLS接続(Docker+Nginx+Let's Encrypt)

DockerコンテナによるFlexisipのTLS接続

NginxリバースプロキシとLet’sEncryptによるSSL/TLS接続をサポートするDockerコンテナを利用して、FlexisipをTLS接続に対応させます。Dockerによる新たなブリッジネットワークnginx-proxyを作成し、全てのコンテナをこのネットワーク内で稼働します。

Dockerブリッジネットワークnginx-proxyの作成

$ docker network create nginx-proxy

ネットワークの確認

$ docker network inspect nginx-proxy

Docker共有ボリューム"shared"の作成

docker-composeにより作成されたコンテナ間でLetsencryptによる認証ファイルを共有するためのボリュームを予め作成します。

$ docker volume create shared

ボリューム一覧・確認

$ docker volume ls
$ docker volume inspect shared
[
    {
        "CreatedAt": "2019-11-10T20:52:30+09:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/shared/_data",
        "Name": "shared",
        "Options": {},
        "Scope": "local"
    }
]

Docker-Composeファイルnginx-lets.ymlを作成

以下Nginx-ProxyとLet’s EncryptによるTLS認証をサポートするイメージからComposeファイルを作成します。
ファイルの格納場所は任意です(但し、FlexisipのComposeファイルと同一のディレクトリは避けて下さい)。

nginx-proxy

LetsEncrypt companion container for nginx-proxy

nginx-lets.yml

version: '2'

services:
  nginx-proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - shared:/etc/nginx/certs
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    restart: always
    networks:
      - proxy-tier
      
  nginx-proxy-letsencrypt:
    container_name: nginx-proxy-letsencrypt
    image: jrcs/letsencrypt-nginx-proxy-companion
    volumes_from:
      - nginx-proxy:rw
    volumes:  
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - DEFAULT_EMAIL=ficus.online@gmail.com
    restart: always
    networks:
      - proxy-tier

networks:
  proxy-tier:
    external:
      name: nginx-proxy
      
volumes:
  shared:
    external: true

上記Composeファイルにより各コンテナを起動します。

$ docker-compose -f nginx-lets.yml up -d

Flexisipコンテナを起動

Docker-Composeファイルは以下参照願います。(UbuntuまたはDebianバージョン)

LetsEncryptによる認証ファイルを共有するためdocker-compose.ymlファイルに以下内容を追加します。

version: '3'

services:
........................
.......................  
    volumes: これをubuntu(debisn)-flexisipの項目に追加
      - shared:/etc/flexisip/tls
       
..........................
.........................
volumes: これを最後尾に追加
  shared:
    external: true

上記ComposeファイルによりFlexisipを起動します。
デフォルトのファイル名docker-compose.ymlの場合、ファイル名を指定する必要はありません。

$ docker-compose up -d

FlexisipのTLS設定

中間証明書chain.pemとサーバ証明書(認証局から配布)cert.pemを連結したfullchain.pemからcafile.pemファイルを、サーバ証明書cert.pemとプライベートキーkey.pemからagent.pemファイルを作成します。

$ docker exec -ti ubuntu(debian)-flexisip bash
# cd /etc/flexisip/tls/www.example.com
# ls
account_key.json  cert.pem  chain.pem  fullchain.pem  key.pem
    
# cp fullchain.pem cafile.pem
# awk 1 key.pem cert.pem > agent.pem

/etc/flexisip/flexisip.confのTLS認証の箇所を編集します。

transports=sips:www.example.com:5071;maddr=172.18.0.5

tls-certificates-dir=/etc/flexisip/tls/www.example.com/

最後にFlexisipコンテナを再起動します。

$ docker container restart ubuntu(debian)-flexisip 

<オプション>SNMPを起動する場合

ubuntu(debian)-flexisipコンテナへアクセス、execコマンドによるbashスクリプトを実行

$ docker exec -ti ubuntu(debian)-flexisip /etc/init.d/snmpd start

またはflexisipコンテナ起動時にexecコマンドによるbashスクリプトを実行してSNMPを起動

$ docker container start ubuntu(debian)-flexisip && docker exec -it ubuntu(debian)-flexisip /etc/init.d/snmpd start

Notes

ネットワーク系のコンポジットコンテナ Nginx+Let’s EncryptFlexisip と切り離すことで、別アプリである FreePBX(Asterisk) の稼働にもこのコンポジットコンテナを利用できます。

コンポジット設定ファイルを “version:3” に対応させる場合は以下の様になります。

nginx-lets.yml

version: '3'

services:
  nginx-proxy:
    container_name: nginx-proxy
    image: jwilder/nginx-proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - shared:/etc/nginx/certs
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    labels:
      - "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy"
    restart: always
    networks:
      - proxy-tier
      
  nginx-proxy-letsencrypt:
    container_name: nginx-proxy-letsencrypt
    image: jrcs/letsencrypt-nginx-proxy-companion
    depends_on:
      - "nginx-proxy"
    volumes:
      - shared:/etc/nginx/certs
      - ./vhost:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html 
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - DEFAULT_EMAIL=ficus.online@gmail.com
    restart: always
    networks:
      - proxy-tier

networks:
  proxy-tier:
    external:
      name: nginx-proxy
      
volumes:
  shared:
    external: true

参考サイト

コンテナへの特権付与:cap_add, privileged

version: '3'

services:
  flexisip-mariadb:
    container_name: flexisip-mariadb
    image: mariadb
    restart: always
...
...

  ubuntu-flexisip:
    container_name: ubuntu-flexisip

## コンテナにネットワークに関わる特権を付与
    cap_add:
      - NET_ADMIN
    privileged: true
...

http://man7.org/linux/man-pages/man7/capabilities.7.html

CAP_NET_ADMIN
              Perform various network-related operations:
              * interface configuration;
              * administration of IP firewall, masquerading, and accounting;
              * modify routing tables;
              * bind to any address for transparent proxying;
              * set type-of-service (TOS)
              * clear driver statistics;
              * set promiscuous mode;
              * enabling multicasting;
              * use setsockopt(2) to set the following socket options:
                SO_DEBUG, SO_MARK, SO_PRIORITY (for a priority outside the
                range 0 to 6), SO_RCVBUFFORCE, and SO_SNDBUFFORCE.

SIP: Session Initiation Protocol

This document describes Session Initiation Protocol (SIP), an
application-layer control (signaling) protocol for creating,
modifying, and terminating sessions with one or more participants.
These sessions include Internet telephone calls, multimedia
distribution, and multimedia conferences.
SIP invitations used to create sessions carry session descriptions
that allow participants to agree on a set of compatible media types.
SIP makes use of elements called proxy servers to help route requests
to the user’s current location, authenticate and authorize users for
services, implement provider call-routing policies, and provide
features to users. SIP also provides a registration function that
allows users to upload their current locations for use by proxy
servers. SIP runs on top of several different transport protocols.

Ways of VoIP encryption : TLS, SRTP

TLS:セッションの確立(SIPプロトコル)を暗号化
SRTP:音声・ビデオ通話の暗号化

For instance, an organization has remote offices in multiple locations and with PSTN Gateways. In this case, all possible call legs at the head office and the remote offices and voice gateways must be encrypted. By doing this, you are encrypting and securing data and voice packets crossing LAN, WAN/VPN. Let us have a look at two ways of VoIP encryption:

  1. One option is SIP Signalling Encryption using Transport Layer Security (TLS). With this setup, all the information is passed on from the client to the server. TLS which needs a secure certificate to identify each side, is used here for SIP signalling payload encryption.

  2. SRTP (Secure Real-Time Transport Protocol) is the secure version of RTP. It is used to deliver audio and video over IP protocol with encryption, message authentication and integrity. To strengthen the security and VoIP encryption methods, TLS should be used with SRTP on all VoIP systems. This ensures SIP signalling and voice/video sessions are end-to-end encrypted and safe from any malicious activity.

SRTP Overview
https://www.dialogic.com/webhelp/BorderNet2020/2.1.0/WebHelp/srtp_ov.htm