Ubuntu を無線 LAN ルータとして稼働させる


## 三行で説明すると
- hostapd 起動して
- DHCP サーバ立てて
- iptables でパケット転送する

## 環境
使ったマシンは、ThinkPad0T430s。
OS version は、Ubuntu 12.04。
`wlan0` で端末から接続受けて、`eth0` でインターネットに流す。

## hostapd の設定
hostpad をインストール。

```bash
sudo apt-get install hostapd
```

設定ファイルのテンプレがここにあるみたい。
`/usr/share/doc/hostapd/examples/hostapd.conf.gz`

こいつをありがたくいただく。

```bash
sudo zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz > /etc/hostapd/hostapd.conf
```

続いて、`/etc/hostapd/hostapd.conf` を編集。修正したのは、これらの項目。
ssid/passphrase あたりはお好みで。

```bash
driver=nl80211
ssid=test-ubuntu
hw_mode=g
channel=1
wpa=2
wpa_passphrase=testubuntu
```

軽く動作確認。

```bash
$ sudo hostapd /etc/hostapd/hostapd.conf
Configuration file: /etc/hostapd/hostapd.conf
Failed to update rate sets in kernel module
Using interface wlan0 with hwaddr 84:3a:4b:20:b9:40 and ssid 'test-ubuntu'
```

この状態で、別の端末で無線アクセスポイントの一覧眺めて、`test-ubuntu` が見えてれば OK。

基本デーモンとして動かす予定なので、`/etc/default/hostapd` に設定ファイルのパスを追加しておく。

```bash
DAEMON_CONF="/etch/hostapd/hostapd.conf"

```

で、`hostapd` 起動しておく。

```bash
$ sudo service hostapd restart
 * Stopping advanced IEEE 802.11 management hostapd [ OK ]
 * Starting advanced IEEE 802.11 management hostapd [ OK ]
$ ps aux | grep hostapd | grep -v grep
root      7212  0.5  0.0  33468  1220 ?        Ss   18:14   0:00 /usr/sbin/hostapd -B -P /var/run/hostapd.pid /etc/hostapd/hostapd.conf
```

## DHCP の設定
DHCP サーバをインストール。`isc-dhcp-server` を採用。

```bash
sudo apt-get install isc-dhcp-server
```

`/etc/dhcp/dhcpd.conf` の末尾に、繋ぎにきた端末に払い出す IP アドレスのリース情報を追記。
IP 体系はお好みで。既存の NW 構成とバッティングしない程度に気を配って。

```bash
subnet 192.168.126.0 netmask 255.255.255.0 {
  range 192.168.126.10 192.168.126.254;
  option domain-name-servers 8.8.8.8;
  option routers 192.168.126.1;
  default-lease-time 600;
  max-lease-time 7200;
}
```

`hostapd` 同様、デーモンで動かすので、`/etc/default/isc-dhcp-server` に使用するインタフェースを追加。

```bash
INTERFACES="wlan0"
```

`wlan0` に、DHCP 設定と矛盾無いように IP アドレスを設定。

```bash
$ sudo ifconfig wlan0 192.168.126.1 netmask 255.255.255.0

```

で、`dhcpd` 起動しておく。

```bash
$ sudo service isc-dhcp-server restart
stop: Unknown instance: 
isc-dhcp-server start/running, process 7225
$ ps aux | grep dhcpd | grep -v grep
dhcpd     7225  0.0  0.0  18808  4512 ?        Ss   18:14   0:00 /usr/sbin/dhcpd -f -q -4 -pf /run/dhcp-server/dhcpd.pid -cf /etc/dhcp/dhcpd.conf wlan0
```

## iptables の設定

`net.ipv4.ip_forward` という IP フォワーディングのカーネルパラメータがあるので、こいつを有効にする。

```bash
$ sudo sysctl -w net.ipv4.ip_forward=1
```

端末から受信した `wlan0` 宛のパケットを、`eth0` に流してやる。
NAT テーブルに追加。

```bash
$ sudo iptables -t nat -A POSTROUTING -s 192.168.126.0/24 -o eth0 -j MASQUERADE
```

NAT テーブル確認すると、こんな感じ。

```bash
$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
MASQUERADE  all  --  192.168.126.0/24     anywhere
```

以上で、無線 LAN ルータ完成。

ちなみに、NAT テーブルから上記ルールを削除するときは `-D` で。

```bash
$ sudo iptables -t nat -D POSTROUTING -s 192.168.126.0/24 -o eth0 -j MASQUERADE
```

## エラー事例

### nl80211 driver initialization failed.

無線デバイス (wlan0) を有効にしていなかったので、有効にしたら解決。

```bash
$ sudo hostapd /etc/hostapd/hostapd.conf 
Configuration file: /etc/hostapd/hostapd.conf
Could not set interface mon.wlan0 flags: Operation not possible due to RF-kill
nl80211: Failed to set interface wlan0 into AP mode
nl80211 driver initialization failed.
rmdir[ctrl_interface]: No such file or directory
ELOOP: remaining socket: sock=4 eloop_data=0xfe81f0 user_data=0xfeb0a0 handler=0x4339e0
ELOOP: remaining socket: sock=6 eloop_data=0xfed870 user_data=(nil) handler=0x43ce30
```

### wlan0: IEEE 802.11 Hardware does not support configured channel


デフォで `hostapd.conf` に設定されている hw_mode と channel が、このマシンだとダメっぽい。
`hw_mode=a` (IEEE 802.11a) を `hw_mode=g` (IEEE 802.11g) に変更。
あわせて、`channel=60` を `channel=1` に変更。

```bash
$ sudo hostapd /etc/hostapd/hostapd.conf 
Configuration file: /etc/hostapd/hostapd.conf
wlan0: IEEE 802.11 Configured channel (60) not found from the channel list of current mode (2) IEEE 802.11a
wlan0: IEEE 802.11 Hardware does not support configured channel
Could not select hw_mode and channel. (-1)
wlan0: Unable to setup interface.
rmdir[ctrl_interface]: No such file or directory
```

### DHCP でうまく IP アドレスが払い出されない

自分の場合だと、端末側は `DHCP Discover` を送信するも、Ubuntu 側の `wlan0` でそれを受信できていないってケースが。
他の無線 LAN とバッティングしてよからぬ状況になってるかな、ってことで、使用するチャンネルを変更したら解決した。
`channel=1` の部分を `channel=11` とか、少しズラしてあげるといいんじゃないかなと。

## 参考にさせていただいた資料
- https://github.com/tatsuya6502/rensai_arm/blob/master/02/hostapd-example.conf
- http://tmtms.hatenablog.com/entry/2012/11/17/002416