Ubuntu PCをオンデマンド起動のWiFiアクセスポイントにする

(2019/12/8追記) 本記事よりも良い方法が見つかったので、別記事にまとめました。

最近はデスクトップPCにWiFiアダプタが付いていることも多く、実際自分がUbuntu18.04を動かしているPCも有線LANアダプタだけ使ってWiFiアダプタが余っている状態。そこで今回は、この浮いているWiFiアダプタを有効活用し、デバッグ用のWiFiアクセスポイントを構築する。

PCをアクセスポイントにするメリットは、特殊なことをしなくても無線LANに流れる全てのパケットをtcpdumpなどでキャプチャ出来ること。これは何かとデバッグに役立つと思う。

デバッグ用途ということもあって、「オンデマンド起動」つまりコマンドラインで必要な時だけWiFiアクセスポイントを起動できるような設定を目指す。

  • (2019/8/27追記)アクセスポイント化には、wpa_supplicantではなくhostapdを使うのが一般的のようだ。こちらの記事でhostapdによる設定方法も試している。まぁでも、hostapdはデーモンなのでCtrl-Cで止められないし、wpa_supplicant使ったアクセスポイントもデバッグ用としてはアリだし役に立つケースもあるんじゃないかと…
スポンサーリンク

想定するネットワーク構成

WiFiアダプタによる接続の他に、インターネット接続が設定されているものとする。

WiFi端末(192.168.11.*) <-> wlp2s0
                              |
                         Ubuntu PC
                              |
                           enp1s0 <-> ルーター(10.0.0.1) <-> Internet

PCはwlp2s0を介してWiFi LAN(192.168.11.)へ、enp1s0を介して有線LAN(10.0.0.)へと接続されている状態。

とりあえず端末からWiFi接続出来るようにする

まずは、WiFiアダプタの確認。lshwを実行して、WiFiアダプタ(下ではwlp2s0)が見つかればOK。見つからない場合はドライバのインストール等設定が必要。

$ sudo lshw -class network -short
H/W path               デバイス  クラス      詳細
==========================================================
/0/100/13/0            enp1s0        network        RTL8111/8168/8411 PCI Express Gigabit Ethernet Controll
/0/100/13.3/0          wlp2s0        network        Dual Band Wireless-AC 3168NGW [Stone Peak]

端末からの無線接続を受け入れるだけなら、wpa_supplicantを使えば簡単。以下の記述をしたファイルをwpa_supplicant_ap.confというファイル名で保存し、

wpa_supplicant_ap.conf

ctrl_interface=/var/run/wpa_supplicant
network={
    ssid="SSID"
    mode=2
    key_mgmt=WPA-PSK
    psk="passcode"
    frequency=2437
}

以下を実行するだけで、端末側にはWiFiアクセスポイントのリストに表示されるようになる。

$ sudo wpa_supplicant -iwlp2s0 -c./wpa_supplicant_ap.conf

このまま端末を接続させても、リンクが張られているるだけ(有線LANで言えばケーブルを繋いだだだけ)なので、通信は出来ない。IPアドレスなど、ネットワーク設定を行う必要がある。

WiFiアダプタのIPアドレス設定

上記のネットワーク構成となるよう、WiFi LAN側アドレスを192.168.11.1に設定する場合は以下のコマンドを実行すればよい。

$ sudo ip address add 192.168.11.1/24 dev wlp2s0

DHCPサーバの起動

端末にIPアドレスを配るためDHCPサーバを立てる。まずはインストール。

$ sudo apt-get install isc-dhcp-server

以下のように設定ファイルを作成。
デフォルトルートに自分(192.168.11.1)を、
ネームサーバはルータ(10.0.0.1)を指定している。

/etc/dhcp/dhcpd.conf

default-lease-time 600;
max-lease-time 7200;

ddns-update-style none;
authoritative;

subnet 192.168.11.0 netmask 255.255.255.0 {
  range 192.168.11.10 192.168.11.100;
  option routers 192.168.11.1;
  option subnet-mask 255.255.255.0;
  option domain-name-servers 10.0.0.1;
}

DHCPサーバを起動。

$ sudo systemctl start isc-dhcp-server

…と、起動しない。/var/log/syslogを確認すると、エラーを吐いている。

Aug 18 16:04:05 ubuntu dhcpd[6579]: Not configured to listen on any interfaces!
               :
Aug 18 16:04:05 ubuntu dhcpd[6579]: 
Aug 18 16:04:05 ubuntu dhcpd[6579]: exiting.

原因は、対象のネットワーク(192.168.11.0)でアダプタが動いてないせいのようだ。上記でIPアドレスを設定した筈だが、それだけではダメでlinkを上げておく必要がある。というわけで、以下のコマンドを実行後にDHCPサーバを起動させればOK。

$ sudo ip link set wlp2s0 up

NATの設定

WiFi LANと有線LANとの間でパケットのやりとりを出来るようにするための設定。

/etc/sysctl.confにIPv4 forward有効化の設定(再起動しないと反映されないので注意)。

net.ipv4.ip_forward=1

iptablesを使ってNATの設定をする。
既存の設定をクリアしてから(例えばnat -Fなど)設定したいところだが、
iptablesを間接的に使っているufwの設定もろとも消えてしまうため、
今回はufwと干渉しないようにWiFi用のNATに必要な設定だけを追加で行う。

$ sudo iptables -A FORWARD -i wlp2s0 -o enp1s0 -s 192.168.11.0/24 -j ACCEPT
$ sudo iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
$ sudo iptables -t nat -A POSTROUTING -o enp1s0 -s 192.168.11.0/24 -j MASQUERADE

WiFiアクセスポイントとして起動

上記の、

  1. WiFiアダプタのIPアドレス設定
  2. DHCPサーバの起動
  3. NATの設定

をひととおり実行した後、あらためて上記と同様にwpa_supplicantを実行すると、無事インターネット接続可能なアクセスポイントを起動させることが出来た。

$ sudo wpa_supplicant -iwlp2s0 -c./wpa_supplicant_ap.conf

更に、ctrl-Cで実行を止めると、WiFiアクセスポイントも終了するようになった。
これで、オンデマンドでWiFiアクセスポイントを起動する準備は完了。

あとは上記1〜3がブート時に自動設定されるようにすれば完成。

ブート時の設定をする

上記の

  • WiFiアダプタにIPアドレスが設定されてリンクが上がってないとDHCPサーバが起動しない

という問題は要するに「ブート時にWiFiアダプタのIPアドレスを設定しリンクを上げれば良い」なのだが、実は結構厄介でだいぶハマった。当初はnetplanで設定しようとしたのだが、
netplanに以下のような設定をしても、WiFiアダプタwlp2s0にIPアドレスが設定されない。

/etc/netplan/01-network-manager-all.yaml

  wifis:
    wlp2s0:
      dhcp4: false
      dhcp6: false
      addresses: [192.168.11.1/24]
      critical: true

仕方ないので、古い仕組みではあるがifupdownでWiFiアダプタの設定を行うことにした。

$ sudo apt-get install ifupdown

でインストール後、以下のような設定ファイルを作成すればOK。

/etc/network/interfaces

auto wlp2s0
 iface wlp2s0 inet static
     netmask 255.255.255.0
     broadcast 192.168.11.255
     address 192.168.11.1

DHCPは元々systemdサービスで設定しているので、以下を実行すれば自動起動する。

$ sudo systemctl enable isc-dhcp-server.service

残り、iptablesがけっこう曲者。そもそもUbuntu18.04ではufw(要はiptablesのラッパーなんだが)が推奨されていて、iptablesは非推奨となっている。このため、昔のようにiptablesの設定を何も考えずに保存して良い仕様とはなってないようだ(ufwを覚えろという話もあるが…)。

とはいえ、Ubuntu18.04には救済策?としてiptables-persistentが用意されている。

$ sudo apt-get install iptables-persistent

インストール前に上記のiptables設定を実行しておくと、/etc/iptables/rules.v4に設定が保存される。設定しない状態でインストールしてしまった場合は、上記のiptablesコマンドを実行したうえで、

$ sudo /etc/init.d/netfilter-persistent save

を実行すると、/etc/iptables/rules.v4に保存され、再起動後も有効となる。

コメント