ラズパイをWi-Fiアクセスポイント化

ラズパイをアクセスポイント化して、PCからラズパイに直接アクセスします。

目的:なぜアクセスポイント化するのか?

CoderDojo青梅の会場にはWi-Fiルータがひとつしかありません。例えば10人が参加するとき、ひとつのWi-Fiルーターには合計20個以上のデバイスが同時接続してネットワークが混みあいます(ラズパイを10個、ノートPCを10台)。そもそも、このWi-Fiルータのパッケージ箱には同時接続推奨4台と記載されています。
■現状: 【PC】→【Wi-Fiルータ】→【ラズパイ】 2ホップでつながる
■IPアドレスDHCP自動割り当て:[192.168.1.0]~[192.168.1.255]

もしWi-Fiルーターにラズパイだけを接続して、ノートPCはラズパイに直接接続できたらWi-Fiルーターの負荷が減りますよね。ノートPCとラズパイ間のアクセスも直接接続するので(ホップ数が減るので)高速化するのではないでしょうか。これを検証します。
■変更後: 【PC】→【ラズパイ】 1ホップでつながる
■IPアドレス事前割り当て:[192.168.249.*] …*の部分はみんなで重複しない数字を決める(1~254)

目的を変更:Wi-Fiルーターが無い場所で、ノートPCからラズパイにアクセスする

下図にはWi-Fiルータの絵があるが、ノートPCとラズパイだけで接続できることを検証する

設定手順

手順1.仮想Wi-Fiインターフェース追加
手順2.アクセスポイント機能[hostapd]追加
手順3.DNSフォワーダー&DHCPサーバー機能[dnsmasq]追加
手順4.DHCPクライアント機能[dhcpcd]設定
手順5.動作確認
手順6.リモートデスクトップ接続
手順7.SSHターミナル接続
手順8.Proxyサーバー[squid]設定

OS

OSは、CoderDojo青梅で配布した最新の RaspberryPi OS を使います

Linuxコマンドでの設定

ラズパイのターミナル[>_]を起動する

印刷すると便利な用語集と構成図

手順1.仮想Wi-Fiインターフェースを追加する

1-1. ラズパイに無線LAN(Wi-Fiインターフェース)[wlan0]が存在することを確認する

$ ip a
1: lo:            ループバックアダプタ ~~~ inet 127.0.0.1(自分自身のアドレス)
2: eth0:          イーサネットアダプタ …有線LAN
3: wlan0:         無線LANアダプタ ~~~ inet 192.168.1.(自分のアドレス)/24

1-2. Linuxの[iw]コマンドで新しい仮想WiFiインターフェース[ap0]を追加する

$ sudo iw phy phy0 interface add ap0 type __ap
                                         ↑ここはアンダーバーが2つ

(補足:下記□の位置にスペースを入れる)
$ sudo□iw□phy□phy0□interface□add□ap0□type□__ap

1-3. [ip a]コマンドで[ap0]のMACアドレスを調べる
下記例のように b8:~~~~:f1が同じなら 手順1-5へ進む。なお、まだ[ap0]にIPアドレスを設定していません。

3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether b8:27:eb:0c:29:f1 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.17/24 brd 192.168.1.255 scope global dynamic noprefixroute wlan0
       valid_lft 13981sec preferred_lft 12181sec
    inet6 2405:6580:c6e0:0:6542:c9ee:9d90:3919/64 scope global dynamic mngtmpaddr noprefixroute 
       valid_lft 13975sec preferred_lft 12175sec
    inet6 fe80::a4ec:f8cd:396:38d2/64 scope link 
       valid_lft forever preferred_lft forever
4: ap0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
    link/ether b8:27:eb:0c:29:f1 brd ff:ff:ff:ff:ff:ff

もしも、[ap0]のMACアドレスと[wlan0]のMACアドレスと異なる場合、仮想Wi-Fiインターフェースを、自分のラズパイのMACアドレス(物理的な番号)に書き換える(下線の部分を書き換える)

$ sudo ip link set ap0 address de:a6:32:a8:e0:24
                                  ↑自分のwlan0と同じMACアドレスにする

1-4. ラズパイに[ap0]が追加されたことを確認する( [$ iw dev]で確認してもよい )

$ ip a
4: ap0:      … が追加されていること。 IPアドレスはまだ未設定

1-5. 仮想WiFiインターフェースをデバイス(udev)として設定
ラズパイを再起動しても[ap0]が消えないように、永久的にデバイス(udev)を設定する(あとで再起動して確認する)。
まず、viエディタもしくはnanoエディタを使って新しい空のファイル[/etc/udev/rules.d/99-ap0.rules]を作成する。

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

もしくは

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

1-6. いま作成したファイル「99-ap0.rules」に下記の設定を入力する
( 下線のdc:a6:32:a8:e0:24 の部分はサンプルです。実際には自分のwlan0と同じMACアドレスに置き換える。2か所)
[\]は一行で書くところを改行して読みやすくしていることを意味している
そしてファイルを保存して閉じる。

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"

手順2.アクセスポイント機能[hostapd]をインストール

$ sudo apt install hostapd

続行しますか? [Y/n] と聞かれたら、 [y] キーを押す。

手順3.DHCPサーバー機能[dnsmasq]をインストール&設定

$ sudo apt install dnsmasq

3-1. 下記の設定ファイル(コンフィグファイル)にDHCPで割り当てるIPアドレスを追加する

viエディタもしくはnanoエディタでフィル「dnsmasq.conf」を開く。

$ sudo vi /etc/dnsmasq.conf

3-2. DHCPサーバーの設定を追加する
「dnsmasq.conf」ファイルを一番下までスクロールして、最終行に、アクセスポイントと、PCに自動割り当てするアドレス範囲を追加する。下記設定は、りゅうじくんのDHCPサーバーIP範囲です。自分の[DHCPサーバーIP範囲]を入力する(下線部分だけ変更)。
りゅうじくんの場合:dhcp-range = DHCPサーバーIP範囲の最初の192.168.249.50, 次が192.168.249.59, 最後はみんな同じ255.255.255.0,12hです。(0~254の範囲。dhcp-range=リースする最初のアドレス,リースする最後のアドレス,リース期間)
そしてファイルを保存して閉じる。

interface = ap0
dhcp-range = 192.168.249.50, 192.168.249.59, 255.255.255.0, 12h
俺のIPアドレスをメモしておくこと

手順4.DHCPクライアント機能[dhcpcd]の設定

4-1. 下記ファイルに、ラズパイ[ap0]のIPアドレスを固定に設定する
viエディタもしくはnanoエディタで[dhcpcd.conf]ファイルを開きます。

$ sudo vi /etc/dhcpcd.conf

4-2. ファイルの最終行に、IPアドレスを追加する
下記はりゅうじくんの場合のサンプルです。IPアドレスは自分のIPアドレスを記入します(下線部分だけ変更)。
そしてファイルを保存して閉じる。

interface ap0
static ip_address=192.168.249.1/24
nohook wpa_supplicant

4-3. 無線LANのアクセスポイント[hostapd.conf]を設定
viエディタまたはnanoエディタで、新しい空のファイルを作成する。

$ sudo vi /etc/hostapd/hostapd.conf

4-4. アクセスポイントを設定する
いま作成したファイル「hostapd.conf」に下記を転記します。自分の名前の部分は例えば[KANO]つまり KANO_WIFI などを設定する。シークレットキーも設定します。合わせて下線部分を2箇所変更する。
そしてファイルを保存して閉じる。

ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
interface=ap0
driver=nl80211
ssid=自分の名前_WIFI
hw_mode=g
country_code=JP
channel=11
ieee80211d=1
wmm_enabled=0
macaddr_acl=0
auth_algs=1
wpa=2
wpa_passphrase=自分の名前_PASSWORD
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP

手順5.動作確認(Wi-Fiアクセスポイントが動作していること)

5-1. 設定したアプリを全て再起動する

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

もし「Unit hostapd.service is masked.」というエラーが表示された場合、次の手順で hostapdサービスを起動してください。

$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl start hostapd

5-2. 仮想WiFiインターフェースにIPアドレスが割り当てられていること

$ ip a
4: ap0: ………
  link/ether [wlan0と同じMACアドレス]
  inet 192.168.249.55 はサンプル。実際は自分のラズパイのアクセスポイントap0

5-3. ノートPC(Windows)のネットワークで自分専用の俺Wi-Fiが見つかること

5-4. Windows PC のWiFiアクセス先を[福祉センターWi-Fiルータ]から[自分の俺Wi-Fi]へ変更する

(変更前)PC → 福祉センターのWiFiアクセスポイントは、WiFiを切断(無効化)する。

(変更後)PC → 自分のラズパイWiFiアクセスポイントは、WiFiを接続(有効化)する

参考にしたURL https://www.mikan-tech.net/entry/raspi-wifi-ap-sta

手順6.リモートデスクトップ接続

6-1. Windowsからラズパイの俺IPアドレスが応答することを検査する

c:\ ping 192.168.249.*
Reply from 192.168.249.*: bytes=32 time=5ms TTL=64
Reply from 192.168.249.*: bytes=32 time=6ms TTL=64

6-2. Windowsでリモートデスクトップ接続を起動し、自分のIPアドレスで接続する

手順7.SSHターミナル接続

7-1. ラズパイの設定メニュー > インターフェイス > SSH を有効にする
7-2. ラズパイの設定メニュー > インターフェイス > VNC も有効にしておく
[OK]ボタンを押す

7-3. Windows コマンドプロンプトを起動し、ラズパイの俺IPアドレスが応答することを検査する

c:\ ping 192.168.249.*
Reply from 192.168.249.*: bytes=32 time=5ms TTL=64
Reply from 192.168.249.*: bytes=32 time=6ms TTL=64

7-4. Windows コマンドプロンプトから、ラズパイの俺IPアドレスにSSHターミナル接続する

c:\ ssh pi@192.168.249.*

初めてSSH接続するときは、接続先のサーバーが本当に自分のラズパイなのか分かりません(ニセモノのラズパイの可能性もあります)。そこでフィンガープリント(指紋)という公開鍵のハッシュ値が使われます。ネットワークは公開鍵🔒と秘密鍵🔑を使ってSSH暗号通信をします(仕組みの説明は省略しますね)。下記メッセージが表示されたら「yes」を入力します。

The authenticity of host '192.168.249.*' can't be established.
ED25519 key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxx
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? _

OSログイン用のユーザ名[pi]に対するログイン用パスワード[デフォルトは raspberry]を入力する

pi@192.168.249.*'s password: __

ラズパイのターミナルが表示されたらSSH接続に成功。[ls]コマンドで自分の知っているファイルが見つかることを検査しましょう。

pi@raspberrypi:~ $ _

これからは、Windowsで python プログラム を書いてからラズパイにプログラムを転送します。
Linux の vi エディタなどに慣れたら、SSH接続のターミナルでプログラムを編集してもかまいません。
以上

インターネット接続したいよね(Proxyサーバー)

ここまで設定したのはWi-Fiアクセスポイントだけ。せっかくならPCからラズパイ経由でインターネットにもアクセスしたいよね。ここではイカを使います。今度はProxyサーバーというデーモンを搭載しますが、アプリの名前はスクイッド(Squid)、日本語でイカです。

手順8. Proxyサーバーをインストールする

ラズパイがインターネットに接続していることを確認してください。下記のコマンドでSquidをインストールします。

$ sudo apt-get install squid

Squidの設定ファイル「squid.conf」を編集できるようにファイルの権限を[777に]変更します。

$ sudo chmod 777 /etc/squid/squid.conf

Squidの設定ファイル「squid.conf」に下記1行を追加します。このアドレスはWindowsパソコンに割り当てたIPアドレスのネットワークです。つまりWindowsパソコン側からのインターネットアクセスを許可するための設定です。

acl localnet src 192.168.249.0/24

これは参考です

# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 0.0.0.1-0.255.255.255  # RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8             # RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10          # RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16         # RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12          # RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16         # RFC 1918 local private network (LAN)
acl localnet src fc00::/7               # RFC 4193 local private network range
acl localnet src fe80::/10              # RFC 4291 link-local (directly plugged) machines
acl localnet src 192.168.249.0/24       # Kano ★ここを追加しました。

acl SSL_ports port 443
acl Safe_ports port 80          # http
acl Safe_ports port 21          # ftp
acl Safe_ports port 443         # https

ap0インタフェースとwlan0インタフェースの間をルーティングし、さらにNAPT(IP masqueradem)も設定します。“/etc/sysctl.conf”を編集してIP routingをオンにします。

$ sudo nano /etc/sysctl.conf

下記の行からコメントアウトします(# を消します)

# Uncomment the next line to enable packet forwarding for IPv4
#net.ipv4.ip_forward=1

  ↓

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1

接続されたデバイスがインターネットに接続できるよう、「IPマスカレード(Windowsパソコンからのアクセスは wlan0 に転送する)」を設定します。以下のコマンドを入力します。IP masqueradeを設定します。Windowsパソコンからのアクセスは、ラズパイを経由してwlan0からインターネットのWi-Fiルーターに転送されます。

$  sudo iptables -t nat -A  POSTROUTING -o wlan0 -j MASQUERADE

iptables とは、セキュリティ・ファイアウォールの事です。コマンドの機能は次の通り

-t nat:natテーブルを使用する
-A POSTROUTING:POSTROUTINGチェインを使用し、内部ネットワークから外部ネットワークへ出ていくパケットのソースIPを書き換える
-o eth0:パケットが出ていくインタフェースを指定する(ここでは「eth0」)
-j MASQUERADE:IPマスカレードを行う

そして次のコマンドでIPマスカレードの設定を保存しています。↓コピペの時、下記のダブルクォーテーションが “ “(半角) になっていること注意。

$ sudo sh -c "iptables-save > /etc/iptables.ipv4.nat"

最後に、上記のコマンドがラズパイが起動する際に実行されるように「rc.logal」のファイルを編集します。以下のコマンドでnanoを起動します。

$ sudo nano /etc/rc.local

rc.localファイルの中で「exit 0」とある行の前に、以下の内容を追記します。

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

(参考)ファイル「/etc/rc.local」の中身

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
iptables-restore < /etc/iptables.ipv4.nat
exit 0

ここで設定を反映させるために一度、再起動しましょう

$ sudo reboot

WindowsパソコンからラズパイのWi-Fiアクセスポイントに接続するときのメッセージが変わったはずです。

まとめ

これでWi-Fiルータの無い場所でも、ノートPCからラズパイにSSH接続やRDP接続ができるようになった。モバイルバッテリーがあれば屋外でもラズパイを操作できるぞ。


備考

もし「Unit hostapd.service is masked.」というエラーが表示された場合、次の手順で hostapdサービスを起動してください。

$ sudo systemctl unmask hostapd
$ sudo systemctl enable hostapd
$ sudo systemctl start hostapd

もし「hostapd」のステータスが[activating]で起動されないとき


■試行1
If passphrase is left out, it will be read from stdin
Passphrase must be 8..63 characters
usage: wpa_passphrase <ssid> [passphrase]

パスフレーズが8文字以上63文字以下で設定されているか確認。
wpa_passphrase = 12345678

■試行2
$ hostapd -d -v 
もしくは権限がなければ
$ sudo hostapd -d -v 
でデーモン化(常時起動)せずに、コマンドで起動して出力される詳細なエラーログを読む。

■試行3
自分の設定ファイルで起動してエラーログの変化を読む。
$ sudo hostapd /etc/hostapd/hostapd.conf -d
または
$ sudo hostapd /etc/hostapd/hostapd.conf -dd

コメントを残す