みかんのゆるふわ技術ブログ

Raspberry PiやIoT関係のことを書き残していきます

Raspberry Pi WiFiアクセスポイント+クライアント同時使用

前回の記事で、Raspberry PiをWiFiアクセスポイント化してスタンドアロン運用ができるようにしました。

www.mikan-tech.net

実はRaspberry PiはWiFiネットワークに接続しながら自分自身がWiFiアクセスポイントになることができます。 外付けUSB-WiFiなどを用意せず、Raspberry Piの機能だけでできるので便利です😆

この方法で設定してWiFiクライアント機能を使わずスタンドアロン運用もできます。 前回の記事よりわずかに手間が増えますが大差ないので、両対応できるこの記事の方法でセットアップするのも良いでしょう。

今回はWiFiアクセスポイントとクライアントを別ネットワークとしてセットアップします。

Raspberry PiをおうちのWiFiにつなげてRaspberry Piのアクセスポイント機能を有効したとします。 スマホからは家のWiFiとRaspberry PiのWiFiの2つが見えるようになります。 スマホをRaspberry PiのWiFiにつないだ場合、スマホは家のWiFiから切り離され、インターネットにも接続できず、Raspberry Piだけと通信できます。

例えば、普段はRaspberry Piを持ち運んでスタンドアロンで使い、たまに家のWiFiにもつなぎたい場合に便利です。

次のステップとして、Raspberry PiのWiFiにつなぐと家のWiFiやインターネットにもつながるようにできます。 つまり市販のWiFiルーターのようにする形ですね。これは次回の記事で説明します。

この記事ではRaspberry Pi OS Lite (CUI版) bullseyeを使用しています。Desktop(GUI)版などNetwork Managerが入っている環境ではこの方法は使えないと思いますのでご注意ください。

ネットワーク構成

上の図の通り、Raspberry PiをWiFiクライアント兼アクセスポイントにします。

WiFiクライアント機能

WiFiクライアント機能で家のWiFiネットワークに接続します。こちらはDHCPでIPアドレスを取得します。

家のWiFiネットワークのSSIDはMIKAN_HOME_WIFI、パスワードはMIKAN_HOME_PASSWORDとします。

こちらは既に設定済とします。

WiFiアクセスポイント機能

WiFiアクセスポイント機能のSSIDMIKAN_NO_WIFIパスワードMIKAN_NO_PASSWORDとします。 また、アクセスポイント側のIPアドレス192.168.249.1にしました。

接続しに来るスマホやパソコンにIPアドレスを配布するためにアクセスポイント側にDHCPサーバー機能ももたせます。 DHCPで配布するアドレスは192.168.249.50192.168.249.150にしました。

設定方法

ソフトウェアアクセスポイント機能を実現するhostapdと、 DNSフォワーダー&DHCPサーバー機能を持つdnsmasqを使用します。

ここでは、Raspberry Piを家のWiFiネットワークにつないだ状態で作業しました。 ただ、WiFi設定をいじるので間違えるとWiFiが切れてしまう可能性もあるので、有線LANで作業したほうが無難です。

仮想WiFiインターフェースの作成

Raspberry PiはデフォルトのWiFiインターフェースとしてwlan0があります。iw devコマンドで見ると、

$ iw dev
phy#0
        Unnamed/non-netdev interface
                wdev 0x2
                addr de:a6:32:a8:e0:24
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 3
                wdev 0x1
                addr dc:a6:32:a8:e0:24
                ssid MIKAN_HOME_WIFI
                type managed
                channel 116 (5580 MHz), width: 80 MHz, center1: 5610 MHz
                txpower 31.00 dBm

のように、WiFi物理デバイスにwlan0というインターフェースが割り当てられていることがわかります。

よく見るとtxpowerが1ワット越え!?(31dBm)😳とびっくりしますが、これは公称の最大出力が表示されているだけで、実際の送信電力は法規制に準拠した値になるみたいです。

前回の記事ではwlan0をアクセスポイントとして使いました。 今回はwlan0は家のWiFiにつないだまま、もう1つ仮想WiFiインターフェースを作成してそちらをアクセスポイントとして使います。

$ sudo iw phy phy0 interface add ap0 type __ap
$ sudo ip link set ap0 address de:a6:32:a8:e0:24

1行目でap0という名前の仮想インターフェースを作成しました。2行目でap0のMACアドレスを設定します。 MACアドレスはwlan0と同じでよいでしょう。結果を見てみましょう。

$ iw dev
phy#0
        Interface ap0
                ifindex 4
                wdev 0x3
                addr de:a6:32:a8:e0:24
                type AP
                channel 116 (5580 MHz), width: 80 MHz, center1: 5610 MHz
                txpower 31.00 dBm
        Unnamed/non-netdev interface
                wdev 0x2
                addr de:a6:32:a8:e0:24
                type P2P-device
                txpower 31.00 dBm
        Interface wlan0
                ifindex 3
                wdev 0x1
                addr dc:a6:32:a8:e0:24
                ssid MIKAN_HOME_WIFI
                type managed
                channel 116 (5580 MHz), width: 80 MHz, center1: 5610 MHz
                txpower 31.00 dBm

wlan0に加えap0というインターフェースができました。

wlan0はこれまで通りクライアントに、ap0をアクセスポイントとしてセットアップしていきます。

udevの設定

WiFiインターフェースはRaspberry Piを再起動すると元に戻り、ap0は消えてしまいます。 再起動後もap0が使えるように、起動時にap0を作成するよう設定しましょう。

udevの仕組みを使います。/etc/udev/rules.d/99-ap0.rulesというファイルを作成します。例えばvimを使うなら

$ sudo vim /etc/udev/rules.d/99-ap0.rules

とします。中身は次の通りにします。

SUBSYSTEM=="ieee80211", ACTION=="add|change", ATTR{macaddress}=="dc:a6:32:a8:e0:24", KERNEL=="phy0", \
  RUN+="/sbin/iw phy phy0 interface add ap0 type __ap", \
  RUN+="/bin/ip link set ap0 address dc:a6:32:a8:e0:24"

なお上記MACアドレスの値はiw devの結果を見てお使いのRaspberry Piに合わせて変えてください。 これをそのままコピペしても動かないので注意!🙅‍♀️

これでRaspberry Piの起動時にudevが自動的にap0を作ります。

必要なパッケージのインストール

続いて、hostapddnsmasqをインストールしましょう。

$ sudo apt install hostapd dnsmasq

これだけでインストールできます。簡単ですね。

DHCPサーバーの設定(dnsmasq)

dnsmasqの設定ファイル/etc/dnsmasq.confを編集します。 例えばvimで編集するには次のようにします。

$ sudo vim /etc/dnsmasq.conf

ファイルの最後に以下の行を追加します。

interface=ap0
dhcp-range=192.168.249.50,192.168.249.150,255.255.255.0,12h

先ほど作成した仮想インターフェースap0でdnsmasqのDHCPサーバー機能が有効になります。

WiFiクライアント側(wlan0)や有線LAN(eth0)には影響しませんのでご安心ください。

DHCPクライアントの設定(dhcpcd)

続いて、自分自身のIPアドレスを固定するために、/etc/dhcpcd.confを編集します。 このファイルはDHCPクライアント機能の設定ファイルです。

$ sudo vim /etc/dhcpcd.conf

ファイルの最後に以下の3行を追加しましょう。

interface ap0
static ip_address=192.168.249.1/24
nohook wpa_supplicant

これでアクセスポイント側(ap0)のIPアドレを192.168.249.1に固定します。

なお、WiFiクライアント側(wlan0)や有線LAN(eth0)はこれまで通りDHCPが使えます。

hostapdの設定

続いて、hostapdの設定を行います。設定ファイルは自動では生成されないようです。 自分で/etc/hostapd/hostapd.confというファイルを作成しましょう。例えばvimだと、次のコマンドです。

$ sudo vim /etc/hostapd/hostapd.conf

ファイルの内容は次のようにします。

ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=MIKAN_NO_WIFI
hw_mode=g
country_code=JP
channel=11
ieee80211d=1
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=MIKAN_NO_PASSWORD
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

hw_mode=gとしていますが、これは2.4GHz帯のIEEE802.11gの通信方式を指定しています。 channel=11で11chを使っていますが、1~13chが使えます(Raspberry Piでは14chは使えないみたい?)。

また、hw_mode=aとすると、5GHz帯のIEEE802.11aが使えますが、法規制上レーダーとの干渉を防ぐための機能を有効にする必要があるなど 設定を見直す必要があります。なお、hw_modeを変えた場合はchannelも5GHz帯のものに合わせて変える必要があります。

ssidの行とwpa_passphraseの行は自分のSSIDやパスワードにあわせて変えてください。

hostapdはaptでインストールしても自動では有効になりません。 以下のコマンドで起動時に自動でhostapdが立ち上がるように設定しましょう。

$ sudo systemctl unmask hostapd.service
$ sudo systemctl enable hostapd.service

おめでとうございます。これで設定が完了です!

WiFiの有効化

Raspberry Piのインストール直後はWiFiが無効になっています。 国ごとに電波の規制が異なるので、国コードを設定するまでは電波を出さないためだと思います。

私はここまでWiFi経由で作業してきましたが、有線LAN経由で作業していてまだWiFiを有効にしていない方は、WiFiを有効化しましょう。

/etc/wpa_supplicant/wpa_supplicant.confを編集します。

$ sudo vim /etc/wpa_supplicant/wpa_supplicant.conf

このファイルに次の行を追加します。

country=JP

ファイルを保存後、次のコマンドでWiFiを有効にします。

$ sudo rfkill unblock wifi

これでWiFiが有効になります。

動作確認の準備

動作確認のときに分かりやすいので、WebサーバーのNginxをインストールします。

ブラウザでアクセスすると、Nginxのデフォルトページが見えます。

$ sudo apt install nginx

動作確認

設定ファイルの反映

設定したhostapd、dnsmasq、dhcpcdを再起動しましょう。

$ sudo systemctl restart dhcpcd.service
$ sudo systemctl restart hostapd.service
$ sudo systemctl restart dnsmasq.service

これでWiFiアクセスポイント機能が起動します。

スマホやパソコンからWiFiアクセスポイントを探してみます。

うまくいけば、このようにWiFiアクセスポイントが見えるはずです。パスワードを入力すると接続できます。

インターネットに接続されていません、という表示になります。

Raspberry Piは家のWiFiに接続していますが、Raspberry Piのアクセスポイントは家のネットワークとは独立しており、 ここから直接家のネットワークに入ったり、インターネットにアクセスすることはできません。

接続できれば、ブラウザでhttp://192.168.249.1/ または http://raspberrypi.local/ (ホスト名を変更した場合はrapberrypiの部分を設定したホスト名にする)でアクセスできます。

このように、Nginxのデフォルトページが見えました。おめでとうございます!🎊

再起動

ここまでくれば、さっそく再起動して動作確認しましょう。

$ sudo reboot

再起動しても同じように自動でアクセスポイントが起動し、スマホやパソコンから接続できるはずです。

これで家のネットワークとは関係なく、Raspberry Piに直接アクセスできますね。 Raspberry Piを外に持ち出しても直接アクセスできるので便利です。

Raspberry PiのWiFiアクセスポイントに接続した機器からもインターネットにアクセスしたい場合は次の記事を参考にしてください。

www.mikan-tech.net

参考文献

この記事はGitHubリポジトリやブログを参考に、/etc/network/interfacesを使わないなどBullseyeに対応するように手順を変更しています。

github.com

blog.thewalr.us

また、hostapdの設定はこちらの記事を参考にさせていただきました。

qiita.com