Raspberry Pi 2 Model BでScapyを書いていると、リモートデバッグしたくなりました。
そこで、IntelliJのremote interpreter方式を使って、Raspbian上のScapyをリモートデバッグしてみた時のメモを残します。
目次
環境
- Mac OS X 10.11.6
- Raspberry Pi 2 Model B (以降ラズパイ)
公開鍵を使ったSSHを可能にするよう設定
以前、
pi@raspberrypi:~ $ sudo raspi-config
から 5 Interfacing Options > P2 SSH
にて enabled
してありますので、その設定の続きです。
今回は、以下を参考に実施しました。
ツール・ラボ » Raspberry Piに公開鍵認証を使ってssh接続する
なお、今回はパスワード認証もとりあえず残しておきます。
以下ログです。
# Macにてキーペアの作成 $ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa_raspberry_pi # scpにてMacからラズパイへ公開鍵を転送 $ scp -P 22 ~/.ssh/id_rsa_raspberry_pi.pub pi@192.168.10.50: pi@192.168.10.50's password: id_rsa_raspberry_pi.pub # ラズパイにて転送されていることを確認 pi@raspberrypi:~ $ ls -al id* -rw-r--r-- 1 pi pi 757 Jan 7 13:49 id_rsa_raspberry_pi.pub # 鍵を移動して権限を設定 pi@raspberrypi:~ $ mkdir .ssh pi@raspberrypi:~ $ cat id_rsa_raspberry_pi.pub >> .ssh/authorized_keys pi@raspberrypi:~ $ chmod 700 .ssh pi@raspberrypi:~ $ chmod 600 .ssh/authorized_keys # 末尾に追加 pi@raspberrypi:~ $ sudo vi /etc/ssh/sshd_config # 以下3行を追加 RSAAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile %h/.ssh/authorized_keys # 不要な公開鍵を削除してSSHを再起動 pi@raspberrypi:~ $ rm id_rsa_raspberry_pi.pub pi@raspberrypi:~ $ sudo /etc/init.d/ssh restart [ ok ] Restarting ssh (via systemctl): ssh.service. # Macより公開鍵認証でSSHできることを確認 $ ssh -i ~/.ssh/id_rsa_raspberry_pi pi@192.168.10.50 Linux raspberrypi 4.9.59-v7+ #1047 SMP Sun Oct 29 12:19:23 GMT 2017 armv7l ... pi@raspberrypi:~ $
IntelliJを使ったリモートデバッグ設定
- Python Debug Server方式
- remote interpreter方式
の2つがあるようです。
PyCharmのリモートデバッグ機能を使ってみる - Qiita
今回は、以下を参考にSSHを使うremote interpreter方式を使ってみました。
PyCharmを使ってRaspberry Pi2上で快適リモートGPIOプログラミング - izm_11's blog
以下、作業ログです。
- 既存のScapyプロジェクトを開く
- Project Structureを開く
File > Project Structure
- Python SDKをローカルから切り替える
Project > Project SDK > New > Python SDK > Add Remote
- リモート設定は以下
項目 | 設定値 |
---|---|
接続方式 | SSH Credentials |
Host | 192.168.10.50 (必要に応じて差し替え) |
User name | pi |
Auth type | Key pair (OpenSSH or PuTTY) |
Private key file | /path/to/.ssh/id_rsa_raspberry_pi |
Python interpreter path | /usr/bin/python (デフォルト値) |
- パスマッピングを実施
- メニューの
Tools > Deployment > Configuration
- 左上の
+
ボタン - 設定内容は以下
- メニューの
タブ | 設定 | 項目値 |
---|---|---|
Connection | Name | (任意の名前) |
Visible only for this project | チェックする | |
Type | SFTP | |
SFTP Host | 192.168.10.50 | |
Port | 22 | |
Path | / | |
User name | pi | |
Auth type | Key pair (OpenSSH or PuTTY) | |
Private key file | /path/to/.ssh/id_rsa_raspberry_pi | |
Mappings | Local path | /path/to/マッピング元 |
Deployment path on server | /home/pi/scapy_sample |
- ファイルのアップロード
- アップロードしたいファイルを開いた状態で、
Tools > Deployment > Upload to <サーバ名>
- ディレクトリ階層があれば、その階層も含めてアップロードされる
- アップロードしたいファイルを開いた状態で、
- アップロードの自動化
Tools > Deployment > Automatic Upload
にチェックを入れる
以上で、Macとラズパイとでファイルの同期が取れるようになりました。
Scapyのための設定変更
今回は、以前使用したDHCPサーバを探すファイルをリモートデバッグしてみます。
https://github.com/thinkAmi-sandbox/scapy-sample/blob/master/dhcp/discover_dhcp_server.py
まず、ラズパイ上で実行するため、インタフェース名を変更しておきます。
USB_INTERFACE_NAME = 'eth0'
また、Scapyを実行するにはsudoする必要があります。ただ、通常のリモートデバッグではsudoした状態にはなりません。
そこで今回は、システムのPythonの権限まわりを変更しました。
Remote Debug GPIO on Raspberry Pi | Nathan Jones
あまり良くないのかもしれませんが、ラズパイということで今回は気にしないことにします。
pi@raspberrypi:~ $ sudo chown -v root:root /usr/bin/python ownership of '/usr/bin/python' retained as root:root pi@raspberrypi:~ $ sudo chmod -v u+s /usr/bin/python mode of '/usr/bin/python' changed from 0755 (rwxr-xr-x) to 4755 (rwsr-xr-x)
リモートデバッグの実行
まずは、上記で変更を加えたファイルをラズパイへ転送します。
ブレークポイントを置いてデバッグ実行してみると、ブレークポイントで停止しました。
デバッグを続行すると、コンソールに以下が表示されました。
なお、DHCPサーバを探すためのパケット送信が止まらないので、 Cmd + F2
で止める必要があります。
ssh://pi@192.168.10.50:22/usr/bin/python -u /home/pi/.pycharm_helpers/pydev/pydevd.py --cmd-line --multiproc --qt-support=auto --client '0.0.0.0' --port 36797 --file /home/pi/scapy_sample/dhcp/discover_dhcp_server.py pydev debugger: process 1661 is connecting Connected to pydev debugger (build 173.4127.27) ###[ Ethernet ]### dst = FF:FF:FF:FF:FF:FF src = 00:00:00:00:00:04 type = 0x800 ###[ IP ]### version = 4 ihl = None tos = 0x0 len = None id = 1 flags = frag = 0 ttl = 64 proto = udp chksum = None src = 0.0.0.0 dst = 255.255.255.255 \options \ ###[ UDP ]### sport = bootpc dport = bootps len = None chksum = None ###[ BOOTP ]### op = BOOTREQUEST htype = 1 hlen = 6 hops = 0 xid = 0 secs = 0 flags = ciaddr = 0.0.0.0 yiaddr = 0.0.0.0 siaddr = 0.0.0.0 giaddr = 0.0.0.0 chaddr = '\x00\x00\x00\x00\x00\x04' sname = '' file = '' options = 'c\x82Sc' ###[ DHCP options ]### options = [message-type='discover' end] ................Begin emission: Finished to send 1 packets. ....................................*.................................................................................^C Received 134 packets, got 1 answers, remaining 0 packets DHCP Server - MAC: a4:xx:xx:xx:xx:xx, IP: 192.168.10.1
ラズパイへ接続できない環境での注意点
ラズパイへ接続できない環境へ移動して、リモートデバッグ設定をしたプロジェクトを開くと、
Couldn't refresh skeletons for remote interpreter: Error connecting to remote host 192.168.10.50
というメッセージが表示されました。
また、 Automatic update
を有効にしていると、ラズパイへの接続を常に探しているようでした。その結果、ファンが回りっぱなしになるなど、負荷の高まりを感じました。
そのため、ラズパイへ接続できない環境へ移動した場合は、
などを行ったほうが良さそうです。