動機
MiniDLNAには認証や認可の機能がなく、パートナーや家族に見られたくない あんなファイルやこんなファイルを隠す術がありません。そこで、
- 1つのホスト上で複数のMiniDLNAインスタンスを立ち上げて、
- それぞれのインスタンスで公開するディレクトリを変え、
- それぞれのインスタンスにアクセスできるIPアドレスやMACアドレスを制限することにより、
擬似的にアクセス制御を掛けてみることにしました。
これによって、
- このディレクトリはLAN内の全てのDLNAクライアント機器から見えるが、
- あのディレクトリは自分のスマホからしか見えない
というようなことが実現できます。
Dockerfileを記述する
準備が楽なので Docker上でMiniDLNAを動かします。まずはそのためのDockerfileを記述します。
FROM ubuntu:16.04
MAINTAINER flny flny@example.com
RUN apt-get update && apt-get install -y \
minidlna
ADD start.sh /start.sh
RUN chmod +x /start.sh
EXPOSE 8200
EXPOSE 8201
EXPOSE 1900/udp
CMD /start.sh
#!/bin/bash
service minidlna restart
/bin/bash
Ubuntu 16.04では ppaやbackportsなしでMiniDLNAをインストールできます。そのバージョンも1.1.5と新しくなり重大なバグが修正されているので ベースイメージは16.04としました。
また、立ち上げるインスタンスの数だけTCPのポートをEXPOSEに記述します。上記例では8200と8201の2つです。これらとは別に1900/udpも開ける必要があります。
MiniDLNAの設定ファイルを記述する
MiniDLNAの設定ファイル(デフォルトのファイル名はminidlna.conf)をインスタンスの数だけ記述します。
(略)
media_dir=V,/mnt/pub/movie
(略)
# Port number for HTTP traffic (descriptions, SOAP, media transfer).
# This option is mandatory (or it must be specified on the command-line using
# "-p").
port=8200
(略)
# Name that the DLNA server presents to clients.
# Defaults to "hostname: username".
friendly_name=default
(略)
# Serial number the server reports to clients.
# Defaults to 00000000.
serial=681019830597110
uuid=0fc28baa-b6df-4002-9a7f-5994c4b85fc0
(略)
(略)
media_dir=V,/mnt/pub/rated
(略)
# Port number for HTTP traffic (descriptions, SOAP, media transfer).
# This option is mandatory (or it must be specified on the command-line using
# "-p").
port=8201
(略)
# Name that the DLNA server presents to clients.
# Defaults to "hostname: username".
friendly_name=rated
(略)
# Serial number the server reports to clients.
# Defaults to 00000000.
serial=681019830597110
uuid=5a9884be-267d-4164-86c0-d638d98bf09b
(略)
色々な設定が含まれていますが、少なくとも下記のパラメータをインスタンスごとに変更します。
-
media_dir
公開するディレクトリ -
port
ポート番号(DockerfileのEXPOSEに書いたポート) -
friendly_name
クライアントから見たサーバの名称 -
uuid
任意のuuid
uuid
を記述するところがこの記事唯一のポイントです。uuidの記述がないと、インスタンスを複数立ち上げてもクライアントには1つしか認識されません。uuidgenコマンドやOnline UUID Generatorで uuidを生成できます。
docker-compose.yml を記述する
インスタンスの数だけコンテナの定義を記述します。イメージはDockerfileで定義した共通のものを使用しますが、MiniDLNAの設定ファイルはコンテナごとに変えます(volumes:
の部分)。
minidlna:
image: minidlna
container_name: dlna.default
tty: true
net: "host"
volumes:
- ./docker/minidlna/minidlna.default.conf:/etc/minidlna.conf
command:
"/start.sh"
rated:
image: minidlna
container_name: dlna.rated
tty: true
net: "host"
volumes:
- ./docker/minidlna/minidlna.rated.conf:/etc/minidlna.conf
command:
"/start.sh"
コンテナを作成してMiniDLNAインスタンスを起動する
docker build
で イメージ"minidlna"を作成し、docker-compose up
でコンテナを作成します。
$ docker build -t minidlna <Dockerfileのあるディレクトリ>
$ docker-compose up -d minidlna rated
DLNAクライアントを起動して、DLNAサーバが2つ見えたら成功です。
ファイアウォールでアクセス制御する
あとは、特定のDLNAクライアントのIPアドレスやMACアドレスをファイアウォールで弾けばOKです。IPアドレスならufwが簡単でよいですが、MACアドレスだとiptablesを直接使う必要があります。以下はufwの例です。
192.168.0.101 がホストのIPアドレス、192.168.0.201がスマホのIPアドレスだとして、rated(ポート8201)はスマホからしか見えないようにファイアウォールを設定します。
# デフォルトを許可にする
$ sudo ufw default ALLOW
Default incoming policy changed to 'allow'
(be sure to update your rules accordingly)
# ファイアウォールを有効化する
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
# スマホから rated(ポート8201)への接続を許可する
$ sudo ufw allow from 192.168.0.201 to 192.168.0.101 port 8201
Rule added
# スマホ以外から rated(ポート8201)への接続を拒否する
$ sudo ufw deny from any to 192.168.0.101 port 8201
Rule added
これでスマホ以外のクライアントからはratedが見えなくなりました。
以上