Raspberry Pi をWi-Fiアクセスポイント&ルーター化する

[[]]Raspberry PiWi-Fiアクセスポイント&ルーター化してみた話です。
手順はほぼ以下の手順(とてもよくまとまっています)を追っただけなのですが、
http://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/overview
上記ではRTL8192CUを使ったWiFiアダプタのケースが紹介されていますが、ここではそれに加えてmac80211ベースのドライバのケースでもトライしています。(手順が少し変わります)

Wi-Fiルータとしての機能は、以下の3つのものから構成されます。

ルーター機能として、他にもファイアウォール(パケットフィルタリング)やポートマッピングなどいろいろありますが、ここでは扱いません。

ハードウェアの準備

USB Wi-FiアダプタをRaspberry PiのUSBポートに接続します。
アダプタはなんでも良いとは言いきれないのですが、下調べせず適当に購入したものでなんとかなっています。
うちで動作確認したのは

  • Buffalo WLI-UC-GNM

BUFFALO 無線LAN子機 コンパクトモデル 11n技術・11g/b対応 WLI-UC-GNM

BUFFALO 無線LAN子機 コンパクトモデル 11n技術・11g/b対応 WLI-UC-GNM

  • Planex GW-USWExtreme

の2つです。
起動して、ifconfigでwlan0が見えることを確認してください。

Wi-Fiアクセスポイント機能

まずwlan0に固定IPを振ります。

/etc/network/interfaces

iface wlan0 inet static
  address 192.168.11.1
  netmask 255.255.255.0

次に、hostapdをインストールします。

% sudo apt-get install hostapd

ここでhostapdの設定を行うのですが、使用するアダプタ(ドライバ)によって手順が変わってきます。
lsmodして、ドライバを確認します。(以下は8192cuの場合の例)

% /sbin/lsmod
Module                  Size  Used by
 :
8192cu                490353  0 
 :
ドライバが8192cuの場合

apt-getでインストールされるhostapdはこのデバイスに対応していませんので、
http://www.adafruit.com/downloads/adafruit_hostapd.zip
からバイナリをダウンロードします。zipからhostapdが展開されますので、それでオリジナルのバイナリを置き換えます。
RealTekがドライバおよびツールのソースコードを提供しており、それをコンパイルしたもののようです。
 自前でコンパイルを行いたい場合は以下を参照してください。
 http://learn.adafruit.com/setting-up-a-raspberry-pi-as-a-wifi-access-point/compiling-hostapd

% unzip adafruit_hostapd.zip
% sudo mv /usr/sbin/hostapd{,.orig}
% sudo mv hostapd /usr/sbin/

/etc/hostapd/hostapd.conf を以下のように設定します。
driver=rtl871xdrvを指定。
ssid, channel, wpa_passphraseは適宜変更してください。

interface=wlan0
driver=rtl871xdrv
ssid=myssid
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=raspberrypi
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
ドライバがmac80211ベースの場合

こちらもhostapdを入れ替える必要があります。本家のhostapdがサポートしているのですが、apt-getでインストールされるものはバージョンが古く未対応です(そのうち解決するのかもしれません)。
最新のソースからコンパイルします。
http://w1.fi/hostapd/ からソース(hostad-2.0.tar.gz)を落とし、展開します。

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

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

% sudo apt-get 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 を以下のように設定します。
driver=nl80211を指定。
同様にssid, channel, wpa_passphraseは適宜変更してください。

interface=wlan0
driver=nl80211
ssid=myssid
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=raspberrypi
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
共通

hostapdの起動設定をします。
/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 ~/

この時点でhostapdを起動すればアクセスポイントとして動作します。
DHCPは動いていませんので、もしこの状態で試す場合はクライアント側は固定IPで接続します。

% sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf
Configuration file: /etc/hostapd/hostapd.conf
Using interface wlan0 with hwaddr 00:22:cf:45:73:d5 and ssid "myssid"
(クライアントから接続)
wlan0: AP-STA-CONNECTED 00:19:7e:7d:e2:b8
wlan0: STA 00:19:7e:7d:e2:b8 RADIUS: starting accounting session 51FFD0CC-00000000
wlan0: STA 00:19:7e:7d:e2:b8 WPA: pairwise key handshake completed (RSN)

こんな感じで動けばOKです。クライアントからRaspberry Pipingsshなどが通るか確認してみてください。
デーモンとして起動する場合は以下のようにします。

% sudo service hostapd start

また、起動時にサービスとして立ち上げる場合は以下のようにします。

% sudo update-rc.d hostapd enable 

DHCPサーバ機能

isc-dhcp-serverをインストールします。
※ isc-dhcp-server は apt-get update しないと 404 not found でした。

% sudo apt-get update
% sudo apt-get install isc-dhcp-server

/etc/dhcp/dhcpd.conf の設定を行います。グローバルの domain-name と domain-name-servers の設定は外し、subnetの中でそれらを設定しています。
/etc/dhcp/dhcpd.conf(変更した部分のみ抜粋)

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

authoritative;

subnet 192.168.11.0 netmask 255.255.255.0 {
  range 192.168.11.100 192.168.11.199;
  option broadcast-address 192.168.11.255;
  default-lease-time 600;
  max-lease-time 7200;
  # 以下はルーターにする場合
  option routers 192.168.11.1;
  option domain-name "local";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
}

DHCPサーバの起動設定をします。wlan0側にのみDHCPサービスを提供します。
/etc/default/isc-dhcp-server

INTERFACES="wlan0"

サーバを起動します。

% sudo service isc-dhcp-server start

この時点でhostapdを起動すると、DHCP機能つきのアクセスポイントとして動作します。
今度はクライアント側はDHCPで接続できます。設定どおりクライアント側にIPが振られたことを確認してみてください。
ただし、まだRaspberry Piと接続できるだけです。

こちらも起動時にサービスとして立ち上げる場合は下記のようにします。

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

ルーター(IP forwarding または NAT)機能

カーネルの機能なので、サーバー等のインストールはありません。

/etc/sysctl.conf の設定
以下の行のコメントを外して有効にします。

net.ipv4.ip_forward=1

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

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

iptablesの設定
コマンドでIP forwardを設定したあと、その状態をファイルにセーブします。

% 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 sh -c "iptables-save > /etc/iptables.ipv4.nat"

これをネットワーク設定時に読み込む設定にします。
/etc/network/interface の最後に以下の行を追加

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

以上ですべての設定が完了しました。
クライアントから接続し、ルーターとして機能することを確認してください。
有線側をインターネットに接続し適切に設定されていればクライアントからもインターネットにアクセスできるはずです。

他にも、ルーター機能を強化したりネームサーバを走らせたりなどすれば単機能ルータより価値の高いサービスが提供できそうですね。