|
[バックナンバーのトップへ] [Linux システム管理のトップへ] いますぐ実践! Linux システム管理 / Vol.182 / 読者数:1547名こんばんは、うすだです。 この春、 情報処理技術者試験のエンベデッドシステムスペシャリスト試験を受験したのですが、 先月の25日に、ネットで合否が発表されました。 事前の答え合わせでは、なんとも微妙な感じだったので、 どうしてもよい結果を期待してしまっていたのですが、その結果はと言いますと…
…はい、落ちてました。OTZ
しかも、一番できの悪かった午後I が59点で、1点足りませんでした。 もう、昔から、詰めが甘い甘いと言われて育ってきたのですが、またここでも、 詰めの甘さを発揮してしまったようです。
ところで、過去、詰めの甘さが一番際立ったのは、大学受験のときです。 じゃあ今回はと言うと、おそらく、ちょっと勉強しただけで合格すると、 図に乗ってしまい、 後で本人が痛い目に会うとかわいそうだと(ギリギリの神様が)思って、 落としてくれたのだと思います。
ええ、そう思うことにします。そう思いますとも。 …ええ、ショックじゃありませんから、今回もはりきってまいりますよ! 今回のお題 - Linux を UPnP 対応にするLinuxマシンを使ってインターネットにつないでいたり、 社内LANから存在していない(ことになっている) ネットワークを Linux マシンでこっそりつないだりなど、 Linux をルータとして使用するケースが、意外とあるのではないかと推測しております。
どちらの場合も、内部のネットワークを外に見せるわけにはいきません。 しかし、そんなときに困るのが、ポートフォワーディングの設定ではないでしょうか。 ユーザさまから、ちょっとこのポートで外からつながるようにしてほしいんだけど、 とお願いされる度に、設定を追加したり削除したりするのは、骨が折れますよね。 会社のポリシーにもよりますが、柔軟な(悪く言えば放置主義的な)ところであれば、 ユーザさまに、それらの設定を行ってもらえば、管理者の貴重な骨を温存できそうです。 というわけで今回は、Linux マシンを UPnP 対応のルータにしてみたいと思います。 とりあえず動かすLinux を UPnP 対応ルータに仕立て上げるには、linux-igd パッケージを使用します。 Ubuntu や Debian, Fedora などの主要なディストリビューションには、 もれなく用意されているようですので、 いつものように yum や apt などを使ってインストールしてください。 # yum install linux-igd (RedHat 系の場合) # apt-get install linux-igd (Debian 系の場合) 設定ファイルは、以下にあります。 ディストリビューションによってパスが異なりますが、記述すべき内容はほぼ同じです。 /etc/sysconfig/upnpd (RedHat 系の場合) /etc/default/linux-igd (Debian 系の場合) 最小限的には、 外側と内側のネットワーク・インターフェースをそれぞれ指定するだけです。 具体的には、外側のインターフェースを EXTIFACE で指定し、 内側のインターフェースを INTIFACE で指定します。 たとえば、外側が eth1 で内側が eth0 なら、以下のように記述します。 EXTIFACE=eth1 INTIFACE=eth0
あとは、以下の手順で、デーモンを起動するだけです。 # /etc/init.d/upnpd start (RedHat 系の場合) # /etc/init.d/linux-igd start (Debian 系の場合) upnpd は、UPnP からの依頼を受け付け、 ポートフォワーディングなどの設定を iptables コマンドを利用して行います。
基本的な設定は、これだけで OK なはずです。 ただ、ファイアーウォールの設定がされている場合、 うまくつながらない可能性があります。(というか、たぶんつながりません。)
ですので、UPnPを許可する必要がありますが、
ポート番号が決まっているわけではないため、
UPnPだけ許可させるのはかなり難しいように思います。
GNOMEのメニューから、「システム」-「管理」-「ファイアーウォール」を選択して、
「ファイアーウォールの設定」を起動します。 以上で、UPnP がつながるようになるのではないかと思います。
…おっと、あと忘れがちなのが、IPフォワーディングの設定です。
以下のように、procfs で直接設定してもよいですし、
sysctl コマンドを使って設定することもできます。 # echo 1 > /proc/sys/net/ipv4/ip_forward もしくは # sysctl -w net.ipv4.ip_forward=1 動作確認してみる
upnpd が走り始めたところで、実際に設定できるか確認してみましょう。
Vol.181 - UPnP でルータを操作してみる まず、内側のネットワーク上のマシンで、gupnp-universal-cp コマンドを実行します。 すると、出現したウィンドウの左側に、検出したデバイスが表示されますので、 その中に「WANConnectionDevice」があることを確認します。 ありましたら、先頭の三角をクリックして、順に展開していきます。
- WANConnectionDevice
- urn:upnp-org:serviceId:wanipconnection1
+ State variables
+ SetConnectionType
...中略...
+ AddPortMapping
+ DeletePortMapping
+ GetExternalIPAddress
ポートフォワーディングの設定を行うためには、
「AddPortMapping」を右クリックして「Invoke」を選びます。 NewRemoteHost : (ルータの外側のIPアドレス) NewExternalPort : (外からつなげられるルータのポート番号) NewProtocol : (TCP もしくは UDP) NewInternalPort : (フォワード先の内部のマシンのポート番号) NewInternalClient : (内部のマシンのIPアドレス) NewEnabled : (否応なくチェック) NewPortMappingDescription : (お好きな文言を記述) NewLeaseDuration : (使用する期間を秒で指定)
たとえば、以下のように設定して「Invoke」したとしましょう。 NewRemoteHost : 115.146.17.162 (←これはあくまで例ですよ) NewExternalPort : 1080 NewProtocol : TCP NewInternalPort : 80 NewInternalClient : 192.168.1.1 NewEnabled : (チェック) NewPortMappingDescription : Internal web server NewLeaseDuration : 1800 そうしましたら、UPnP対応のルータで、以下のように iptable コマンドを実行します。 # iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination ACCEPT tcp -- 0.0.0.0/0 192.168.1.1 tcp dpt:80 Chain OUTPUT (policy ACCEPT) target prot opt source destination このように、FORWARDチェインに追加されていることがわかります。 具体的に確認するには、外側のマシンから以下にアクセスします。 http://115.146.17.162:1080/ 内側のマシン 192.168.1.1 が提供する WWW のページが表示されることを確認してください。
上記の場合は、NewLeaseDuration に 1800秒を指定しましたので、 30分後に設定が消えますが、それまでに消したい場合や、 NewLeaseDuration を指定しなかった場合は、 DeletePortMapping で消し去る必要があります。 手順は同様で、「DeletePortMapping」を右クリックして「Invoke」し、 以下のように引数を設定して「Invoke」ボタンを押します。 NewRemoteHost : (ルータの外側のIPアドレス) NewExternalPort : (ルータのポート番号) NewProtocol : (TCP もしくは UDP) 先ほどの例にそって具体例を示しますと、以下の通りです。 NewRemoteHost : 115.146.17.162 NewExternalPort : 1080 NewProtocol : TCP 同様に iptables コマンドを実行して、設定が消去されたことを確認することができます。 Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
上記で問題なければ、あとは起動時に upnpd が動作するよう仕込むだけです。 (必要であれば…ですが。) RedHat 系の場合は、chkconfig コマンドで登録します。 # chkconfig upnpd on
Debian 系の場合は、EXTIFACE と INTIFACE が設定されていれば、
起動時に upnpd が動作しますので、特に設定する必要はありません。 セキュリティを考慮してみる
さて、基本的な設定と確認はご紹介し終わりました。 Debian 系の場合、設定ファイルである /etc/default/linux-igd には、 EXTIFACE と INTIFACE の他にも、いくつか設定の項目があります。
その中に、非root ユーザの権限で upnpd を動作させるための設定項目があります。
それが UPNPD_USER です。 では、実際に試してみましょう。
まず、非root なユーザとグループを作成します。 # groupadd -g 254 igd # useradd -u 254 -g 254 -d /etc/linuxigd -s /bin/false igd
ただ、upnpd を動作させるには、各所で root の権限が必要になります。
今回は、細かい説明を省きまして、設定方法だけを簡単にご紹介します。
ケーパビリティの設定には setcap コマンド、参照には getcap コマンドを使用します。
これらは libcap2-bin パッケージにありますので、
もしなければ、インストールしておいてください。
で、upnpdの所有者を igd にして、igd だけが実行できるようにします。 # chown igd.igd /usr/sbin/upnpd # chmod go-rwx /usr/sbin/upnpd # setcap cap_net_admin,cap_net_raw=ep /usr/sbin/upnpd # getcap /usr/sbin/upnpd /usr/sbin/upnpd = cap_net_admin,cap_net_raw+ep 最後の getcap コマンドは、設定の確認のために実行しているだけです。
また、upnpd は iptables コマンドを実行しますが、
iptables コマンドの実行にも root 権限が必要です。 # cp -p `which iptables` /etc/linuxigd/iptables # chown igd.igd /etc/linuxigd/iptables # chmod go-rwx /etc/linuxigd/iptables # setcap cap_net_admin,cap_net_raw=ep /etc/linuxigd/iptables # getcap /etc/linuxigd/iptables /etc/linuxigd/iptables = cap_net_admin,cap_net_raw+ep そして、upnpd が上記の iptables を呼び出すよう、 /etc/upnpd.conf の以下の行を書き換えます。 iptables_location = "/sbin/iptables" を以下に変更 iptables_location = "/etc/linuxigd/iptables" そして、upnpd を起動(再起動)すると、igd ユーザの権限で走行するようになります。 # /etc/init.d/linux-igd start (再起動の場合は restart)
他にも、chroot して起動させる設定項目などがありますが、
今回は確認しているヒマがありませんでした。すみません。 おわりに以上、Linux をUPnP対応ルータに仕立て上げる方法を、ご紹介しました。 まあ、実際問題として、UPnP を会社に導入するのは、 あまり許されないことのように思います。
ここは、Linux でもそんなことができるんだ、というくらいの気持ちで、
さらっと読んでいただければと思います。 宿題の答え前回の宿題は、 UPnP でやりとりするパケットを眺めましょう。 でした。 IPアドレスが 192.168.1.211 の PC で gupnp-universal-cp を起動し、 IPアドレスが 192.168.1.254 のルータとやりとりするところを、 tcpdumpコマンドで取得してみました。
以下のように、upnp_bb_router.log というファイルに、
キャプチャしたデータを記録しています。 # tcpdump -s 1500 -w upnp_bb_router.log host 192.168.1.211 or \ host 192.168.1.254 それでは、以下のように実行して、中身を参照してみましょう。 # tcpdump -n -X -s 1500 -r upnp_bb_router.log | less …とはいえ、やはり見づらいですので、こちらでよきように清書したものを、 以下に示していきます。
まず、コントロールポイントである 192.168.1.211 からマルチキャスト (239.255.255.250:1900)で問い合わせるUDPパケットの中身です。 M-SEARCH * HTTP/1.1 Host: 239.255.255.250:1900 Man: "ssdp:discover" ST: upnp:rootdevice MX: 3 User-Agent: gupnp-universal-cp GSDP/0.7.1
最初の行は、機器を探していますよというお約束的なもので、
2〜3行目もお約束的な文言です。(ので割愛します。)
次に、ルータである 192.168.1.254 からの返事です。 HTTP/1.1 200 OK CACHE-CONTROL: max-age=30 EXT: LOCATION: http://192.168.1.254:5431/upnp/igdevicedesc.xml SERVER: UPnP/1.0 <製品名>/<バージョン> ST: upnp:rootdevice USN: uuid:01234567-89ab-cdef-0123-456789abcdef::upnp:rootdevice
最初の HTTP 云々は、HTTP ではおなじみの文言ですね。
それでは、次のパケットを眺めてみましょう。 GET /upnp/igdevicedesc.xml HTTP/1.1 Host: 192.168.1.254:5431 User-Agent: gupnp-universal-cp GUPnP/0.13.2 DLNADOC/1.50 Accept-Language: ja-jp;q=1, ja;q=0.5
接続先の 192.168.1.254:5431 と GET で指定したパスは、
先ほど返ってきた応答の LOCATION: がもとになっています。
HTTP/1.1 200 OK
SERVER: UPnP/1.0 <製品名>/<バージョン>
DATE: Wed, 29 Aug 2007 07:59:06 GMT
CONTENT-TYPE: text/xml
CONNECTION: close
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion><major>1</major><minor>0</minor></specVersion>
<URLBase>http://192.168.1.254:5431/</URLBase>
<device>
<deviceType>
urn:schemas-upnp-org:device:InternetGatewayDevice:1
</deviceType>
...以下、長いので略...
</device>
</root>
ようするに、どんなデバイスなのか問い合わせているようです。
あと、ExternalIPAddress を得るところを見ておきましょう。
POST /WANCONNECTION/WANIPConnection HTTP/1.1
Host: 192.168.1.254:5431
SOAPAction: "urn:schemas-upnp-org:service:WANIPConnection:1#\
GetExternalIPAddress"
...中略...
<?xml version="1.0"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetExternalIPAddress
xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
</u:GetExternalIPAddress>
</s:Body>
</s:Envelope>
これに対するルータの返事は、以下の通りです。
HTTP/1.1 200 OK
CONTENT-TYPE: text/xml; charset="utf-8"
...中略...
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<s:Body>
<u:GetExternalIPAddressResponse
xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1">
<NewExternalIPAddress>1.2.3.4</NewExternalIPAddress>
</u:GetExternalIPAddressResponse>
</s:Body>
</s:Envelope>
長いですが、要約すると、1.2.3.4 ですよとおっしゃっていますね。
以上、長々と説明してしまいました。
Device Architecture Documents >> UPnP Forum 今回の宿題今回の宿題は、 iptables の設定が変更されたらメールで通知するようにしましょう。 です。 linux-igd によって、 自由に設定変更してください的なポリシーで運用がなされるようになると思います。 ですが、管理者は一切関与しませんよ、と責任を放棄するわけにもいかないのが、 つらいところです。
というわけで、
ユーザが設定変更(ポートフォワーディングの設定を追加したり削除したり)
を行ったときに、その旨をメールで知ることができるとよいのではないか、
と思った次第です。 あとがきちょっと前に、「ヘッテルとフエーテル」という本を読みました。
ヘッテルとフエーテル 金融にまつわるワナや裏側などを、物語形式でわかりやすく教えてくれる本です。 金融にまつわるダークなことが、物語でさらりと書かれていますので、 1時間足らずで読めました。 知っていることもいくつかありましたが、あらためて、 鵜のみにしていてはいけないということを再認識することができました。
さて、上記の転職版的な物語が、「CAREERzine」に掲載されていました。
本当に残酷な転職マネー版グリム童話「幸せをあおる虫」 好きなことを仕事にして裕福になろう、と提唱するある著名人を、 面白くかつ少しせつなく、やり玉に挙げています。
わたしは、(元ネタと思われる)著名人の本を何冊か読んで、
特に疑いなど抱いていませんでしたので、
ターゲットにされたことがショックでした。
ですが、指摘されていることもたしかに一理あります。 ただ問題なのは、どうすれば成功したりよい方向に進んでいけるのかが、 さっぱりわからなくなってしまうことです。 なんだか、裕福や幸せを追い求めても、手に入れるのは難しいんだよ、 と言われている気がしてしまいます。なんだかなぁ…。(-ε-;;
今回も、ここまで読んでいただき、誠にありがとうございました。
「いますぐ実践! Linux システム管理」の解除は、以下からできます。
バックナンバーは、こちらにほぼ全部そろっています。
「栗日記」- 劇のチラシを描いています。栗と関係ない劇なのに栗の絵。 |
▼ トップ ▼ プロフィール ▼ リンク
▼ 作ってみました
▼ せんでん
▼ 最近読んだ本
▼ 気に入ってる本 |