野良Wi-Fiでコンテンツ配信

提供: ディーズガレージ wiki
移動先: 案内検索
ホットスポットAP
ホットスポットAP
ホットスポットAP
ホットスポットAP


再検証のためこの記事は古くなっています。
「野良Wi-Fiでコンテンツ配信2」もご参考にしてください。

公衆無線LAN機能にwebサーバ機能を合体してオリジナルコンテンツに誘導する装置です。
野良Wi-Fiは嫌われてるし危険だし、絶対に接続してはいけないアクセスポイントという認識になってると思います。
しかし、管理運営が明らかなものやショールームや地域や場所、期間限定用なら面白いツールに化けるのかも?と見ました。
野良Wi-FiのCaptivePortalからコンテンツへの誘導を極力自動化することで扱いやすいツールを目指してみます。

このシステムを悪用するとメジャー公衆無線LANに模倣した犯罪工作装置になったり無差別多発的にウイルス感染や乗っ取り遠隔操作、最悪スマートフォン・タブレット・パソコンを破壊する非常に危険な仕組みを持っています。この危険な使い方は一切開示も警告もしません。

検証環境

Raspberry Pi Model Bに有線LANその他モニターやキーボードを取り付け使える状態にします。
加えてUSBのWi-Fiアダプタを取り付けます。
OSは2015-05-05-raspbian-wheezy.img

最新状態にアップデート

$ sudo apt-get update
$ sudo apt-get upgrade

ファームウェア更新

$ sudo rpi-update

再起動

$ sudo reboot

IPの固定

$ sudo leafpad /etc/network/interfaces
auto lo
iface lo inet loopback

iface eth0 inet static
address 192.168.1.184
netmask 255.255.255.0
gateway 192.168.1.1

iface wlan0 inet static
address 10.0.0.1
netmask 255.255.255.0
#pre-up iptables-restore < /etc/iptables.ipv4.nat

hostapdの設定

hostapdをインストール

$ sudo apt-get install hostapd

ドライバの確認

$ /sbin/lsmod

Module                  Size  Used by
 :
mac80211              623160  3 rt2x00lib,rt2x00usb,rt2800lib
 :

以降hostapdの設定を行うが、使用するアダプタ(ドライバ)によって手順が変わる
今回は、mac80211ベース。8192cuの場合はこちら”様を参考
ソースをダウンロード

$ wget http://w1.fi/releases/hostapd-2.0.tar.gz
$ tar xvf hostapd-2.0.tar.gz

コンパイルに以下のパッケージが必要なのでインストール

$ sudo apt-get install libnl-genl-3-dev libssl-dev

ソースツリー内のhostapdに移動
defconfigを.configとしてコピーし、.configにCONFIG_LIBNL32=yを追加してからコンパイル

$ cd hostapd-2.0/hostapd
$ cp defconfig .config
$ echo CONFIG_LIBNL32=y >> .config
$ make

コンパイルされたhostapdでオリジナルのバイナリを置き換え

$ sudo mv /usr/sbin/hostapd{,.orig}
$ sudo mv hostapd /usr/sbin/

/etc/hostapd/hostapd.confの設定

$ sudo leafpad /etc/hostapd/hostapd.conf

新規作成 パスワードなし設定

interface=wlan0
driver=nl80211
ssid=応仁のLAN
country_code=JP
ieee80211d=1
hw_mode=g
channel=11
auth_algs=1
wmm_enabled=0

起動設定

$ sudo leafpad /etc/default/hostapd
DAEMON_CONF="/etc/hostapd/hostapd.conf"

WPASupplicantを無効に
/usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service を削除だが、ホームディレクトリに移動。

$ sudo mv /usr/share/dbus-1/system-services/fi.epitest.hostap.WPASupplicant.service ~/

自動起動を設定

$ sudo update-rc.d hostapd enable

DHCPサーバの設定

isc-dhcp-serverをインストール

$ sudo apt-get install isc-dhcp-server

/etc/dhcp/dhcpd.confの設定

$ sudo leafpad /etc/dhcp/dhcpd.conf

変更部分のみ抜粋

#option domain-name "example.org";
#option domain-name-servers ns1.example.org, ns2.example.org;

authoritative;

subnet 10.0.0.0 netmask 255.255.255.0 {
  range 10.0.0.100 10.0.0.199;
  option broadcast-address 10.0.0.255;
  default-lease-time 600;
  max-lease-time 7200;
  # 以下はルーターにする場合
  option routers 10.0.0.1;
  option domain-name "local";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
}

起動設定
wlan0側にのみDHCPサービスを提供

$ sudo leafpad /etc/default/isc-dhcp-server
INTERFACES="wlan0"

自動起動を設定

$ sudo update-rc.d isc-dhcp-server enable

IP forwardの設定

カーネルの機能なので、インストールはなし
/etc/sysctl.conf の設定

$ sudo leafpad /etc/sysctl.conf

以下の行をコメント削除し有効に

net.ipv4.ip_forward=1

上記は再起動しないと効かないので、今すぐ設定する場合は以下のprocエントリに書き込み

$ sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"

iptablesの設定
コマンドでIP forwardを設定したあと、その状態をrootで保存

$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
$ sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
$ sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
$ sudo su
$ iptables-save > /etc/iptables.ipv4.nat

ネットワーク設定時に読み込む設定
端末がrootなので一度閉じ再度開きなおす

$ sudo leafpad /etc/network/interfaces

以下の行をコメント削除し有効に

pre-up iptables-restore < /etc/iptables.ipv4.nat

再起動

$ sudo reboot

ifconfigで以下のようになっていたらアクセスポイントの構築まで完了

$ ifconfig
eth0      Link encap:イーサネット  ハードウェアアドレス b8:27:eb:22:36:8b 
          inetアドレス:192.168.1.184 ブロードキャスト:192.168.1.255  マスク:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:4347 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:3681 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:4187141 (3.9 MiB)  TXバイト:581587 (567.9 KiB)

lo        Link encap:ローカルループバック  
          inetアドレス:127.0.0.1 マスク:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  メトリック:1
          RXパケット:5 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:5 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:0 
          RXバイト:380 (380.0 B)  TXバイト:380 (380.0 B)

wlan0     Link encap:イーサネット  ハードウェアアドレス cc:e1:d5:40:d6:38 
          inetアドレス:10.0.0.1 ブロードキャスト:10.0.0.255  マスク:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  メトリック:1
          RXパケット:3467 エラー:0 損失:0 オーバラン:0 フレーム:0
          TXパケット:4081 エラー:0 損失:0 オーバラン:0 キャリア:0
      衝突(Collisions):0 TXキュー長:1000 
          RXバイト:522068 (509.8 KiB)  TXバイト:4240765 (4.0 MiB)

Captive Portalの設定

CoovaChilliを使用
CoovaChilli自体にIPアドレスを割り振る機能があるのでDHCPサーバーを無効化

$ sudo service isc-dhcp-server stop

再起動後も起動させない

$ sudo update-rc.d isc-dhcp-server disable

CoovaChilliの設定

ダウンロード s3.amazonaws.comからダウンロードできず他を探しました

$ wget ftp://ftp.br.debian.org/slitaz/sources/packages/c/coova-chilli-1.3.0.tar.gz
$ tar xvf coova-chilli-1.3.0.tar.gz

コンパイルとインストール

$ cd coova-chilli-1.3.0
$ ./configure --enable-miniportal
$ make
$ sudo make install

以下を実行

$ sudo su
$ echo '/usr/local/lib/' >> /etc/ld.so.conf

端末がrootなので一度閉じ再度開きなおす

$ sudo ldconfig 
$ sudo mkdir -p /usr/local/var/ 
$ sudo ln -s /var/run /usr/local/var

wwwディレクトリ以下も必要 configureは不要

$ cd coova-chilli-1.3.0/www
$ sudo make install

ユーザアカウントchilliを追加 パスワードは適当に、標準設定値はリターンで問題なし

$ sudo adduser chilli

/usr/local/etc/chilli/defaultsの設定変更

$ sudo leafpad /usr/local/etc/chilli/defaults

変更部分のみ抜粋

HS_WANIF=eth0
HS_LANIF=wlan0

HS_NETWORK=10.0.0.0
HS_UAMLISTEN=10.0.0.1

HS_DNS1=8.8.8.8
HS_DNS2=8.8.4.4

自動起動を設定

$ sudo leafpad /etc/rc.local

exit 0 の上に追記

/usr/local/etc/init.d/chilli start

haserlの設定

インストール

$ sudo apt-get install haserl

FreeRadiusの設定

インストール

$ sudo apt-get install freeradius

/etc/freeradius/usersを変更

$ sudo leafpad /etc/freeradius/users

末尾に追記 ユーザーを全許可

DEFAULT Auth-Type := ACCEPT
        Reply-Message = "Hello, %{User-Name}",

自動起動を設定

$ sudo update-rc.d freeradius enable

再起動

$ sudo reboot

ログインフォームの整形

自動ログイン雛形

オリジナルフォームに変更

$ sudo leafpad /usr/local/etc/chilli/defaults

変更部分のみ抜粋

#HS_UAMHOMEPAGE=http://\$HS_UAMLISTEN:\$HS_UAMPORT/www/coova.html
HS_UAMFORMAT=http://\$HS_UAMLISTEN:\$HS_UAMUIPORT/www/login.html

login.htmlの新規作成

$ sudo leafpad /usr/local/etc/chilli/www/login.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Cache-control" content="no-cache"/>
<meta http-equiv="Pragma" content="no-cache"/>
<title>Captive Portal</title>
<style>
html {
  font-family:  "Hiragino Kaku Gothic ProN", "游ゴシック", YuGothic, Meiryo, sans-serif;
}
body {
  margin: 0 auto;
  height: 100%;
  background: #fff;
}
#wrapper_splash, #wrapper_ready {
  width: 100%;
  height: 100%;
  position: fixed;
  display: none;
}
.container {
  display: table-cell;
  line-height: 40px;
  vertical-align: middle;
  text-align: center;
}
form {
  display: none;
}
#splash_logo {
  margin-left: 26px;
}
#link {
  font-size: 24px;
  color: #888;
  text-decoration: none;
}
</style>
<script src="ChilliLibrary.js"></script>
<script src="chilliController.js"></script>
<script src="jquery-2.1.4.min.js"></script>
<script>
/* login */
function getElement(e) {
  if(document.all) {
    return document.all[e];
  } else {
    return document.getElementById(e);
  }
} 

function toggle(obj) {
  var el = document.getElementById(obj);
  if (el.style.display != 'none') {
    el.style.display = 'none';
  } else {
    el.style.display = '';
  }
}

var last = 'login';
function toggleAuth(newauth, name) {
  toggle(newauth+'-form');
  toggle(newauth+'-label');
  toggle(last+'-form');
  toggle(last+'-label');
  last=newauth;
}

/* URL switch */
function getURLParam() {
  var vars = [], hash;
  var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
  for(var i = 0; i <hashes.length; i++) {
    hash = hashes[i].split('=');
    vars.push(hash[0]);
    vars[hash[0]] = hash[1];
  }
  return vars;
}

var response;

window.onload = function() {
  response = getURLParam()["res"];
  console.log(response);
  if (response == "notyet" || response == "logoff" || response == "failed") {
    $('#wrapper_splash').css('display', 'table');
    setTimeout(redirect, 3000);
  } else if (response == "success" || response == "already") {
    $('#wrapper_ready').css('display', 'table');
  }
}

function redirect() {
  $('#submit').trigger("click");
}
</script>
</head>
<body>
<div id="wrapper_splash">
  <div class="container">
    <img src="coova_resize.png" id="splash_logo" alt="" border="0" height="53" width="190">
    <br>
    <img src="wait_resize.gif" alt="" border="0" height="32" width="32">
  </div>
</div>
<div id="wrapper_ready">
  <div class="container">
    <a href="http://10.0.0.1:4990/www/contents/index.html" target="_blank" id="link">&gt;&gt; Main Contents</a>
  </div>
</div>
<form name="form" method="post" action="login.chi">
  <input name="username" value="0000">
  <input name="password" value="0000">
  <input id="submit" type="submit" name="button" value="ログイン">
</form>
</body>
</html>

jQueryのダウンロード

https://jquery.com/

jQueryをホームから/usr/local/etc/chilli/wwwディレクトリに移動する場合

$ sudo mv jquery-2.1.4.min.js /usr/local/etc/chilli/www/

Coova resize.png

Wait resize.gif

スプラッシュロゴ、ローディングアイコンをホームから/usr/local/etc/chilli/wwwディレクトリに移動する場合

$ sudo mv coova_resize.png /usr/local/etc/chilli/www/
$ sudo mv wait_resize.gif /usr/local/etc/chilli/www/

コンテンツ雛形

wwwディレクトリ内にcontentsディレクトリを作成

$ cd /usr/local/etc/chilli/www
$ sudo mkdir contents

index.htmlの新規作成

$ sudo leafpad /usr/local/etc/chilli/www/contents/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Main Contents</title>
<style>
html {
  font-family:  "Hiragino Kaku Gothic ProN", "游ゴシック", YuGothic, Meiryo, sans-serif;
}
body {
  margin: 0 auto;
  height: 100%;
  background: #aaa;
  color: #fff;
}
#wrapper {
  width: 100%;
  height: 100%;
  position: fixed;
  display: table;
}
#container {
  display: table-cell;
  line-height: 40px;
  vertical-align: middle;
  text-align: center;
}
p {
  font-size: 24px;
}
</style>
</head>
<body>
<div id="wrapper">
  <div id="container">
    <p>Main Contents</p>
  </div>
</div>
</body>
</html>

認証の調整

WiFi設定のSSID選択後CaptivePortalが起動
この流れが維持できれば毎回ポータルサイトに誘導する手順ができる

デバッグ確認すると2回目以降CaptivePortalが起動することなく自動接続になってしまう
20秒程度でRADIUSサーバのセッションを切ることにする

$ sudo leafpad /usr/local/etc/chilli/defaults

変更部分のみ抜粋

HS_DEFIDLETIMEOUT=20   # Default idle-timeout if not defined by RADIUS (0 for unlimited)

または
HS_DEFSESSIONTIMEOUT=20 # Default session-timeout if not defined by RADIUS (0 for unlimited)

資料
Access Provisioning
The following RADIUS attributes are used to place limits on a session authorized by a RADIUS Access-Accept response:

Session-Timeout = seconds
Standard RADIUS attribute (defined in RFC 2865) for setting the maximum session timeout. The user is logged out after this amount of time; session duration. Also see the defsessiontimeout option in chilli.conf.

Idle-Timeout = seconds
Standard RADIUS attribute (defined in RFC 2865) for setting the maximum idle timeout. The user is logged out after this amount of time of inactivity (no traffic). Also see the defidletimeout option in chilli.conf.

http://coova.org/CoovaChilli/RADIUS

再起動

$ sudo reboot

OSの調整

syslogにavahiのwarning出てるのでサービス停止

$ sudo service avahi-daemon stop
$ sudo update-rc.d -f avahi-daemon remove

kernel lacks cgroups or memory controller not avaiable, not starting cgroups [warn]

$ sudo leafpad /boot/cmdline.txt

変更箇所

rootfstype=ext4 elevator=deadline <span style="color:red">cgroup_enable=memory</span> rootwait

再起動

$ sudo reboot

変更履歴

  • 2015.09.09 公開

参考

http://d.hatena.ne.jp/penkoba/20130806/1375742819
https://www.raspberrypi.org/forums/viewtopic.php?f=82&t=49946
http://thr3a.hatenablog.com/entry/20140515/1400163713