Bluetoothでssh接続

Bluetoothを使ってlinux系OSへSSHをつなぐ方法を記載します
正直詳細についてほとんど理解できていないので、とりあえず「できた」ことに対するメモ程度で残します

## Bluetooth PAN
Bluetoothでネットワークを構築するための手段、今回はこれを利用することでBluetooth上でTCP/IP通信、そしてsshを行います
Bluetooth PAN自体のさらなる説明は[こちら](https://www.wdic.org/w/WDIC/PAN%20%28Bluetooth%29)がわかりやすいかもです
linux OS側をNAPとすることでNAP機能を持たないデバイス(例えば,iPad wi-fiモデル)でも接続することが可能になります

## 環境
### ホスト(NAP)側
- OS

```
"Ubuntu"
  リリース18.10(Cosmic Cuttlefish) 64 ビット
  カーネルLinux 4.18.0-22-generic x86_64
  MATE 1.20.3
```
- ハード  
GPD pocket(初代)  
Bluetooth機器は備え付きのもの

### クライアント側
- Mac book pro 2015モデル  
- iPad pro WI-FIモデル( [blink-shell](https://jblevins.org/log/blink-shell) )  
※クライアント側は通常通りのペアリング含め備え付きの機能しか使わないのでOS等は割愛

## BlueZ
http://www.bluez.org/
linux上でbluetoothを扱うためのCLIアプリケーション及びライブラリ
ラズパイとかでも使われているやつらしい(らしい)

```
$ bluetoothctl --version
bluetoothctl: 5.50
```
※ bluetoothctl は対話用のアプリケーション

## bt-pan
https://github.com/mk-fg/fgtk/blob/master/bt-pan
pythonで作られているNAPサーバ立ち上げ用のscript
BlueZ付属の `pand` というアプリケーションを使うことでもNAPサーバを建てれるようだが、このscriptを使うほうが無難だと思う…
(というかBlueZ 5.50だと `pand` がなくなってる気がする...？)

## 事前準備
以下Ubuntu系OSを前提として書いて行きますが、他のLinuxOSでも適宜読み替えていただければ問題ないと思います

### Installations
- bluez  
apt-getで普通に最新版が取得できました 🤔

```sh
$ sudo apt-get install bluez
```

- bt-pan

```
$ sudo apt-get install dbus

$ sudo apt-get install python-dbus

$ sudo apt install bridge-utils

$ wget https://raw.githubusercontent.com/mk-fg/fgtk/master/bt-pan

$ chmod +x bt-pan
```
d-bus周り&bridge-utilsはpython scriptが中で使っているアプリケーション
d-busはプロセス間通信を実現するためのものらしく、なかなか興味深いのでいつか調べてみたいですね

### Configuration
- ネットワーク  
bt-panにわたすためにネットワークインタフェースをひとつ用意する必要があります
`/etc/network/interfaces` に以下の内容を追記後、再起動が必要になります

```
auto bt-br
iface bt-br inet dhcp
  bridge_ports wlpls0
  bridge_stp off
  bridge_maxwait 1%
```

`wlpls0` は環境に合わせて変更してください、ホスト端末に有線をつないでいる場合は `eh0` とかになるかもしれませんね？
(実はここの設定よく理解していないのです…)

- サービス  
使用する各サービスがアクティブであることを確認します
落ちている場合はstartしましょう

```sh
$ service bluetooth status
● bluetooth.service - Bluetooth service
   Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)
   Active: active (running) since Sat 2019-06-22 22:07:42 JST; 1h 2min ago
     Docs: man:bluetoothd(8)
 Main PID: 1039 (bluetoothd)
   Status: "Running"
    Tasks: 1 (limit: 4915)
   Memory: 2.8M
   CGroup: /system.slice/bluetooth.service
           └─1039 /usr/lib/bluetooth/bluetoothd
```

```sh
$ service dbus status
● dbus.service - D-Bus System Message Bus
   Loaded: loaded (/lib/systemd/system/dbus.service; static; vendor preset: enabled)
   Active: active (running) since Sat 2019-06-22 22:07:42 JST; 1h 3min ago
     Docs: man:dbus-daemon(1)
 Main PID: 1027 (dbus-daemon)
    Tasks: 1 (limit: 4915)
   Memory: 5.2M
   CGroup: /system.slice/dbus.service
           └─1027 /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
```

## NAPサーバの起動
```
$ bt-pan server bt-br
```
第一引数に起動モード、第二引数にネットワークインタフェース名を渡します
今回は使いませんが、clientモードで起動することも可能です
普通にコマンドを叩くと制御が返ってこない(ただのpython scriptなので…)ので
バックグラウンドプロセスとして起動するか複数のターミナルを立ち上げましょう

## Bluetoothペアリング
`bluetoothctl` コマンドを使い、クライアントデバイスとペアリングします

- 対象デバイスの探査

```
$ bluetoothctl
[bluetooth]# scan on
Discovery started
[CHG] Controller 28:ED:E0:XX:XX:XX Discovering: yes
[NEW] Device 36:14:EA:XX:XX:XX <device 名>
[NEW] Device 6D:C8:36:XX:XX:XX <device 名>
[NEW] Device 53:20:3B:XX:XX:XX <device 名>
[CHG] Device 18:65:90:XX:XX:XX ManufacturerData Key: 0x004c
[CHG] Device 18:65:90:XX:XX:XX ManufacturerData Value:
  10 05 0b 1c XX XX XX                             ......}
[bluetooth]# scan off
[bluetooth]# devices
Device 4C:56:9D:XX:XX:XX iPad
Device 18:65:90:XX:XX:XX Mac mini
Device 36:14:EA:XX:XX:XX <device 名>
```
`scan on` コマンドでscanを開始し、周辺にあるbluetoothデバイスを発見します
scanコマンドのみでもdevice名が表示されるので、目当てのデバイスを見つけることはできますが
logが標準出力に流れ続けるので適度なところで `scan off` して `devices` で一覧を表示したほうが人間向きです
後続で使うため、接続したい(させたい)デバイスのMACアドレスをコピります

- ペアリング

```
[bluetooth]# pair <MACアドレス>
[bluetooth]# trust <MACアドレス>
[bluetooth]# connect <MACアドレス>
```
この3コマンドでペアリングを行えます
parコマンドを行ったタイミングで接続先デバイスによっては接続確認が表示されるため、コンソール上と接続先デバイスの両者で対応してください(Apple製品の場合は画面に確認コードとYES/NOが表示されるアレです)

初めてペアリングを行ったタイミングでネットワークインタフェースにIPが割り振られるのでsshのためにコピっておきましょう
(なぜこのタイミングなのかはわかりませんが、scriptの都合なのでしょうか？DHPCの都合なのでしょうか？)

```sh
bt-br:avahi: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 169.254.12.40  netmask 255.255.0.0  broadcast 169.254.255.255
        ether 28:ed:e0:XX:XX:XX  txqueuelen 1000  (イーサネット)
```

## クライアントから接続
ペアリング後、通常どおり上記ネットワークインタフェースに割り振られたIPを使いssh接続を行うことができます(ペアリング後、sshがつながるまで少し時間がかかる？ようです、pingでも撃ちながら待ちましょう)
ただし、Macをクライアントとする場合、ツールバーのBluetoothアイコンから対象デバイスを選択後、「ネットワークへ接続」を選択する必要がありました

---

以上になります
MacOSやWindowsなど標準でNAP機能を持っているOSもあるのでわざわざLinux側をNAPサーバにする必要もないのですが
個人的にiPad pro -> GPD Pocketへ接続したい需要があったので調べて実践して見ました。