航空機のADS-B信号を捉える「ADS-B Feeder Image」をラズパイPVE環境のLXCコンテナで動かす

機運
航空機は、自機の位置情報などをADS-B信号 (Automatic Dependent Surveillance-Broadcast Signal) で送信している。その信号を受信してデータをFlightradar24などにシェアできる「ADS-B Feeder」なるものを、私は3年ほど前に知ったようだ。
おっと。これは知らなかった。ラズパイ余らせるか(謎 /
— Masahiko OHKUBO (@mah_jp) August 21, 2023
> but as a thank you, you'll also receive a free Flightradar24 Business Plan subscription (a USD 499.99/year value).
Add ADS-B coverage - The world's largest ADS-B network | Flightradar24 https://t.co/gMiLNUM5xq
この「ADS-B Feeder」のことを最近また思い出し、かつ、私も子どもも程々にFlightradar24が好きで、利用プランをContributorsにアップグレードしてみたくもあり。いわば機運を感じてやる気も出して、1090MHzのADS-B信号を受信できる受信機、実際にはDVB-T規格のTVチューナーをAliExpressで購入した。
ラズパイをADS-B信号の受信専用機に仕立てる方法は多くのウェブ記事で紹介されているものの、
私は家の中で物理サーバを増やしたくない。そこで別の構築方法を考えた。自宅ITの中核となっている既存のラズパイのPVE環境の中で、「ADS-B Feeder Image」を動かすことができるのか、挑戦することにした。
今回の目標
Proxmox VE (PxVirt) の仮想化ホストとして稼働中のRaspberry Pi 4がある。その仮想化ゲストとしてLXCコンテナを作成し、その中で「ADS-B Feeder Image」の公式Dockerコンテナを動作させる。ポイントになりそうなのは、USB接続する受信機を、LXCコンテナから利用可能にできるのかどうかだ。
目指す構成
新規のADS-B Feeder Image (LXC) を、既存の、USB接続でBluetoothを利用しているHome Assitant (VM) やAsterisk (LXC) などと同居させる。
graph TD
subgraph HW ["Raspberry Pi 4 B+ (Physical)"]
subgraph PVE ["Proxmox VE / PxVirt (Hypervisor)"]
direction TB
subgraph LXC_ADSB ["LXC (Privileged) for ADS-B"]
subgraph Docker ["Docker"]
App["ADS-B Feeder"]
end
end
subgraph LXC_VoIP ["LXC: Asterisk"]
end
subgraph LXC_Others ["LXC: others"]
end
subgraph VM_HA ["VM: Home Assistant"]
end
end
end
NIC1(["🌐 Ethernet Port (NIC1)"]) ---|Network Bridge| PVE
NIC2(["🌐 USB NIC (NIC2)"]) ---|Specific Bridge| LXC_VoIP
USB(["📡 USB Dongle<br/>(RTL2838)"]) -.->|USB Passthrough| LXC_ADSB
BT(["🔹 Bluetooth Dongle"]) -.->|USB Passthrough| VM_HA
%% Styling for a premium look
style HW fill:#f9f9f9,stroke:#333,stroke-width:2px
style PVE fill:#eceff1,stroke:#607d8b,stroke-width:2px
style LXC_ADSB fill:#e1f5fe,stroke:#0288d1,stroke-width:2px
style LXC_VoIP fill:#fff3e0,stroke:#ef6c00,stroke-width:2px
style VM_HA fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
style Docker fill:#e8f5e9,stroke:#43a047,stroke-width:2px
style App fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px,font-weight:bold参考) 標準的な構成
参考として。ラズパイと公式のADS-B Feeder Imageを組み合わせた場合はこの構成になる。
graph TD
subgraph HW ["Raspberry Pi (Physical)"]
subgraph Image ["ADS-B Feeder Image (All-in-one)"]
direction TB
OS["Minimal OS"]
App["ADS-B Feeder"]
OS --- App
end
end
NIC1(["🌐 Ethernet Port (NIC1)"]) --- HW
USB(["📡 USB Dongle<br/>(RTL2838)"]) -.->|Direct Access| Image
%% Styling
style HW fill:#f9f9f9,stroke:#333,stroke-width:2px
style Image fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
style App fill:#c8e6c9,stroke:#2e7d32,stroke-width:2px,font-weight:bold「ADS-B Feeder Image」LXCコンテナの構築方法
Step-1. 機器を用意する
| 項目 | 内容 | 価格 | 備考 |
|---|---|---|---|
| 受信機 | Digital USB 2.0 TV Receiver Stick USB2.0 DVB-T SDR DAB FM HDTV TV Tuner Stick RTL2832U R820T2 Antenna Remote Control For laptop - AliExpress 44 | 3,287円 | 購入日: 2026-04-27 |
| アンテナ | 上記受信機に付属の物 | ||
| サーバ筐体 | Raspberry Pi 4 Model B Rev 1.4 (8GB) |
AliExpressで購入した受信機は上記の写真のUSBドングルタイプで、アンテナ端子の形状はMCX。Linux環境からはUSBデバイスとして次のようにみえる。
$ lsusb | grep RTL
Bus 001 Device 007: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
$ lsusb -t
/: Bus 001.Port 001: Dev 001, Class=root_hub, Driver=xhci_hcd/1p, 480M
|__ Port 001: Dev 002, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 001: Dev 003, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 003: Dev 005, If 0, Class=Hub, Driver=hub/4p, 480M
|__ Port 001: Dev 007, If 0, Class=Vendor Specific Class, Driver=dvb_usb_rtl28xxu, 480M
|__ Port 001: Dev 007, If 1, Class=Vendor Specific Class, Driver=[none], 480M
(snip)Step-2. PVE環境とLXCコンテナの準備を行う
- 適当なPCにUSBドングルを接続して、実際のIDを念のため確認しておく (idVendor=“0bda”, idProduct=“2838” となるはず)
- PVE環境にて次の2つのファイルを用意する
/etc/modprobe.d/blacklist-rtl_adsb.confは、PVE環境にUSBドングル (Realtek RTL2838) を認識させないようにドライバをブラックリスト化するもの。/etc/udev/rules.d/99-rtl-sdr.rulesは、USBドングル (Realtek RTL2838) への一般ユーザへのアクセス権限付与と、HIDドライバの解放を意図するもの。なぜTV受信機なのに「HIDドライバ」が関係してくるかと言うと、このUSBドングルには赤外線受光部が備わっていて、PCのリモコンにもなりうるため。なお、HIDドライバをblacklistに追加するとUSBデバイス全般に影響してそれは困るので、このUSBドングルだけに作用するrulesを用意した。
$ cat /etc/modprobe.d/blacklist-rtl_adsb.conf blacklist dvb_usb_rtl28xxu blacklist rtl2832 blacklist rtl2830 $ cat /etc/udev/rules.d/99-rtl-sdr.rules SUBSYSTEM=="usb", ATTRS{idVendor}=="0bda", ATTRS{idProduct}=="2838", MODE="0666", RUN+="/bin/sh -c 'echo -n $kernel > /sys/bus/usb/drivers/usbhid/unbind || true'" - PVE環境にて次のLXCコンテナを作成する
- Template: Debian (trixie)
- Unprivileged container: No (非特権コンテナではなく特権コンテナへ切り替える)
- ちなみに、LXCコンテナのIPアドレスがPVE環境で固定したものだけではなく、DHCP取得も行われてしまう問題は、次のサービスの停止で一応解決できる
systemctl stop systemd-networkd systemctl disable systemd-networkd
- LXCコンテナにSSHサーバを導入する:
sudo apt install openssh-server - PVE環境にて、LXCコンテナの設定ファイル
/etc/pve/lxc/<LXCコンテナID>.confの最後に次の2行を追加し、LXCコンテナからUSBドングルが見えてかつアクセス可能な状態にする。「bus/usb/001」の001は、Busの001側につないでいることを意味する (実際の環境に合わせた数値にすること)。Devの番号はUSBデバイスの差し替えで変化するので、本設定ではDev番号の指定までは行っていない。lxc.cgroup2.devices.allow: c 189:* rwm lxc.mount.entry: /dev/bus/usb/001 dev/bus/usb/001 none bind,optional,create=dir
- LXCコンテナを再起動し、その後、USBドングルの見え方とrtl_testの実行結果を確認する
$ sudo apt install usbutils rtl-sdr $ ls -al /dev/bus/usb/001/007 crw-rw-rw- 1 root plugdev 189, 6 May 11 01:05 /dev/bus/usb/001/007 $ lsusb | grep RTL Bus 001 Device 007: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T $ rtl_test -t Found 1 device(s): 0: Realtek, RTL2838UHIDIR, SN: 00000001 Using device 0: Generic RTL2832U OEM Detached kernel driver Found Rafael Micro R820T tuner Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6 [R82XX] PLL not locked! Sampling at 2048000 S/s. No E4000 tuner found, aborting. Reattached kernel driver
上記のように、LXCコンテナからUSBデバイスが認識されて「0: Realtek, RTL2838UHIDIR, SN: 00000001」のようにデバイス情報の取得まで正常に行えるならば、Step-2は成功だ。
参考情報として、今回の試行錯誤の途中で遭遇した失敗の例を2つ、挙げておく。表示されるエラー番号は、libusbのenum libusb_errorでの定義に対応しているらしい。
## デバイス情報が正しく読み取れない例 $ rtl_test -t Found 1 device(s): 0: b, x, SN: ? Using device 0: Generic RTL2832U OEM usb_open error -4 Failed to open rtlsdr device #0.
## デバイスがすでに専有されてBUSYな例 $ rtl_test -t Found 1 device(s): 0: Realtek, RTL2838UHIDIR, SN: 00000001 Using device 0: Generic RTL2832U OEM usb_claim_interface error -6 Failed to open rtlsdr device #0.
Step-3. ADS-B Feederを導入する
LXCコンテナのOS (Debian) にログインして、以下の操作を行う。
- ADS-B Feeder Imageのインストーラーの実行に必要なツールを事前導入する:
sudo apt install curl jq - ADSB.imにて、「How to Install」 > 「Linux (more advanced)」にある次の記載を見つける
- On most recent Debian / Ubuntu based Linux systems running on ARM64 or x86 systems, you can install the ADS-B Feeder Image as an app
- 記載部分に書かれた次のコマンドで、インストーラーを実行する:
curl https://raw.githubusercontent.com/dirkhh/adsb-feeder-image/main/src/tools/app-install.sh | sudo bash- 最初は次のものをインストールせよと表示されるので従って実行する:
sudo apt-get install -y python3 python3-flask python3-requests python3-cryptography git docker.io docker-compose - 再度、
curl ...を実行すると、次のような処理が行われて正常終了するはず。$ curl https://raw.githubusercontent.com/dirkhh/adsb-feeder-image/main/src/tools/app-install.sh | sudo bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 8092 100 8092 0 0 1591 0 0:00:05 0:00:05 --:--:-- 1871 You appear to be on a debian-style distribution Cloning into '/tmp/tmp.m32B5HCAHy/adsb-feeder'... remote: Enumerating objects: 42008, done. remote: Counting objects: 100% (4082/4082), done. remote: Compressing objects: 100% (664/664), done. remote: Total 42008 (delta 3655), reused 3480 (delta 3394), pack-reused 37926 (from 5) Receiving objects: 100% (42008/42008), 6.89 MiB | 12.02 MiB/s, done. Resolving deltas: 100% (21636/21636), done. Already on 'main' Your branch is up to date with 'origin/main'. Created symlink '/etc/systemd/system/multi-user.target.wants/adsb-docker.service' → '/usr/lib/systemd/system/adsb-docker.service'. Created symlink '/etc/systemd/system/default.target.wants/adsb-early-boot.service' → '/usr/lib/systemd/system/adsb-early-boot.service'. Created symlink '/etc/systemd/system/multi-user.target.wants/adsb-setup.service' → '/usr/lib/systemd/system/adsb-setup.service'. Created symlink '/etc/systemd/system/timers.target.wants/adsb-update.timer' → '/usr/lib/systemd/system/adsb-update.timer'. Running as unit: adsb-docker-pull.service; invocation ID: 0123456789abcdef0123456789abcdef done installing you can uninstall this software by running sudo bash /opt/adsb/app-uninstall you can access the web interface at http://localhost:1099 or http://192.168.1.20:1099
- 最初は次のものをインストールせよと表示されるので従って実行する:
- 実行結果の最後に表示されているURL
http://<LXCコンテナのIPアドレス>:1099をウェブブラウザで開く
Step-4. GUIでの設定, 動作確認
ADS-B Feeder Imageの設定方法については、今回のPVE/LXC環境とは直接関係しない内容となるので、ここでは省略する。たとえば、【特集】眠っていたRaspberry Piが“航空情報局”に!Flightradar24有料プランを無料で楽しむ裏ワザ - PC Watch > 「ADS-B Feederの初期設定」を参考にして進めればよい。参考程度の画面キャプチャを以下に示す。
- Basic SetupとSupport Info:
- Basic Setup: 自局の緯度・経度・高度を入力し、ADS-BのチェックをONにして、APPLYする
- Support Info: 項目「SDR(s)」にてUSBドングルが認識されていることがわかる
- 1週間ほど運用すると次のような記録が得られる
- Map: 捉えたADS-B信号の範囲が地図上にプロットされる。円形とはかけ離れたかなり歪な形となっているのは、周りに障害物が多い、今回のアンテナ設置状況の影響を多分に受けているのだろうと推測する。
- Performance Graphs: 例えば夜間は激減するなど、日々の時間帯によってADS-B信号の受信レートに周期的な変動があることが分かる。






