Linux: ポートフォワード (web)


ポートフォワード ssh に引き続いて、web のポートフォワードを設定します。
ポートフォワードは、本来はポート22の ssh 用ですが、ポートやプロトコルに関係なく、何でも転送できます。

ラズパイの設定
リモートホストのポート 10080 をラズパイの http ポート 80 に接続します。

$ autossh -M 0 -N -f -R 10080:127.0.0.1:80 foobar@example.com

ブート時にコマンドを実行するには、
テンプレート を元に /etc/init.d/autossh を作成します。

$ sudo chmod 755 /etc/init.d/autossh

パソコンから
WEBブラウザから、リモートホストを経由して、ラズパイに接続します。

http://example.com:10080

ラズパイのWEB画面が表示されれば、OKです。


Linux: ポートフォワード (autossh )


ポートフォワード ssh に続いて、ポートフォワードを設定します。
前回の設定では、不便なことがあります。
(1) いったんリモートホストにログインしてから、ラズパイにログインするという、2段階になる。
(2) 毎回ラズパイから手動で設定する必要がある。

リモートホストの設定
(1) ポートフォワード用のユーザを設定します。

# useradd -m foobar
# passwd foobar

(2) 直接 ラズパイにログインできるようにする
/etc/ssh/sshd_config を編集して、GatewayPorts yes にします。

# vi /etc/ssh/sshd_config

#GatewayPorts  no
GatewayPorts  yes

sshd を再起動する

# /etc/init.d/sshd restart

ラズパイの設定
(1) ユーザ
リモートホストと同様に、ポートフォワード用のユーザを設定した方が望ましいのですが。
今回は、用途が限定されているので、デフォルトの pi を使います。

(2) パスフレーズなしの暗号鍵を作る

$ ssh-keygen -t rsa

Enter file in which to save the key (/home/pi/.ssh/id_rsa): <== このままリターン
Enter passphrase (empty for no passphrase):  <== このままリターン
Enter same passphrase again:  <== このままリターン

(3) 暗号鍵をリモートホストに転送する

$ ssh-copy-id -i ~/.ssh/id_rsa.pub foobar@example.com 

(4) ssh セッションの監視をする
.ssh/config を作成して、30秒毎にアライブを送って、3回でタイムアウトするようにします。

$ cd ~/.ssh/
$ vi config

ServerAliveInterval   30
ServerAliveCountMax   3

(5) autossh をインストールする
ssh は、いったんセッションが切れると、終了します。
autossh は、自動的にセッションをつなぎ直します。

$ sudo apt-get install autossh

(6) リモートホストに接続する

$ autossh -M 0 -N -f -R 10022:127.0.0.1:22 foobar@example.com 

パソコンから
リモートホストを経由して、ラズパイにログインします。
ホスト名はリモートホスト (example.com) ですが、ユーザ名はラズパイ (pi) です。
前回は、いったんリモートホストにログインしてから、ラズパイにログインするという、2段階になりましたが。
今回は、リモートホストに接続すると、そのままラズパイに転送され、ラズパイのログイン画面になります。

$ ssh pi@example.com -p 10022

pi@example.com's password: <== ラズパイのパスワード(raspberry)
pi@rapberrypi ~ $ 

ログイン出来れば、OK

ラズパイの設定
ブート時に自動的にコマンドを実行するようにします。
テンプレート を元に /etc/init.d/autossh を作成します。

$ sudo chmod 755 /etc/init.d/autossh
$ sudo insserv autossh

これで、電源投入時、あるいはリブート時に、自動的にラズパイからリモートホストに接続します。

参考
autossh
Automatically restart SSH sessions and tunnels

SSHD_CONFIG – 日本語マニュアルページ
GatewayPorts (ポート中継の許可)
リモートホストがクライアント側に転送されたポートに接続することを許可するかどうか指定します。
いかなるアドレスからも利用可能にしたい場合は”yes”に。

SSH_CONFIG – 日本語マニュアルページ
ServerAliveInterval (サーバ生存確認の間隔)
一定期間サーバからデータが送られてこないときに、タイムアウトする秒数を設定します。

ServerAliveCountMax (サーバ生存カウント最大値)
ssh がサーバからの返答を確認するまでに、サーバ生存確認メッセージ を何回まで送るかを指定します。

ssh – 日本語マニュアルページ
-f
ssh がコマンドを実行する直前に、バックグラウンドに移行するよう指示します。

-N
リモートコマンドを実行しません。これはポート転送のみをおこないたい場合に便利です。

-p ポート
リモートホストに接続するポートを指定します。


Linux: ポートフォワード (ssh)


ポートフォワード (port forward) とは、ローカルコンピュータの特定のポートに送られてきたデータを、別に用意した通信経路を用いてリモートコンピュータの特定ポートに送信する技術手法です。
インターネット上のサーバー(リモートホスト)から、ローカルネット内のコンピュータにアクセスすることができます。

リモートホストを example.com、ユーザ名を user とします。
今回は、ローカルネット内のコンピュータとして、Raspberry Pi (以下、ラズパイと称す) を使用します。
デフォルトのユーザ名は pi で、パスワードは raspberry です。

ラズパイの設定
リモートホストのポート 10022 をラズパイの ssh ポート 22 に接続します。
直接 ラズパイにログインします。

$ ssh pi@rapberrypi.local

ラズパイにログインしたら、リモートホストに接続します。

$ ssh user@example.com -R 10022:127.0.0.1:22 

user@example.com's password: <== リモートのパスワード
~ $ 

プロンプトが表示されたら、そのままにします。

リモートホストの設定
リモートホストにログインする

$ ssh user@example.com 

リモートホストにログインしたら、ラズパイにログインする

$ ssh pi@localhost -p 10022 

pi@localhost's password: <== ラズパイのパスワード(raspberry)
pi@rapberrypi ~ $ 

ログイン出来れば、OK

参考
ssh – 日本語マニュアルページ
-p ポート
リモートホストに接続するポートを指定します。

-R リモートポート:リモートホスト:ホスト側ポート
与えられたリモートホスト上のポートが、与えられたローカルホスト上のポートに転送されるよう指定します。リモート→ローカルのポート転送。


ラズパイ ブート時にコマンドを実行する ( .bashrc )


ラズパイ(Linux)で、ブート時にコマンドを実行するには、大きく3つ方法があります。
1. サービスデーモンを記述する
2. /etc/rc.local に記述する
3. ユーザ毎の .bashrc を記述する

今回は、3. ユーザ毎の .bashrc を記述する 方法です。

注意
ブート時以外にも、ログインすると、実行されます。
複数回実行されると、不都合なものには、適しません。

/etc/inittab を編集して、ブート時に特定のユーザ (pi) にログインするようにします。

$ sudo nano /etc/inittab

(この行をコメントにして)
# 1:2345:respawn:/sbin/getty --noclear 38400 tty1
(この行を追加する)
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1>/dev/tty1 2>&1

.bashrc を編集して、ログイン時に特定にコマンドを実行するようにします。

$ cd ~
$ nano  .bashrc
(一番最後に実行するコマンドを記述する)
*** &

これで、電源投入時、あるいはリブート時に、特定のコマンドを実行します。

参考
.BASHRC AND .BASH_ALIASES – raspberrypi
ドットファイル


ラズパイ sumobot turn


sumobot turn は、Sumobot が左回転と右回転を繰り返すプログラムです。
sumobot_turn.py と sumobot_turn_check.py の2つがあります。
後者は、前者に、ピンの状態をチェックする処理を追加したものです。

インストール
Github から持ってきて、ラズパイの好きな場所 (例えば /home/pi/sumobot/ ) に置きます。

起動

$ sudo python /home/pi/sumobot/sumobot_turn.py

Sumobot が左回転と右回転を繰り返します。

注意
無線LANでログインして起動してください。
有線LANだと、LANケーブルが絡まります。

自動起動
電源を投入したときに、自動的に起動するようにします。
しかし、常に Sumobot が動き出すと、扱いにくいのです。
sumobot_turn_check.py を使用します。
これは、特定のピン (P13) の状態をチェックして、Sumobot を動かさずに、プログラムを終了する処理を追加したものです。

自動起動するには、/etc/rc.local を変更します。
exit 0 の前に、1行追加します。

$ sudo nano /etc/rc.local
...
# add
python /home/pi/sumobot/sumobot_turn_check.py
exit 0 

ハードの設定
P13(GPIO27) と P17(3.3V) の間に10KΩの抵抗を入れます。
プログラムが自動起動して、Sumobot は動き続けます。
P17(3.3V) に代わりに P14(GND) につなぐと、プログラムは終了して、Sumobot Jr は停止したままです。
20160505_raspi_circuit_p13


ラズパイ カーネルのビルド


Ubuntu環境で、ラズパイのカーネルをビルドする。

ツール
インストール

$ mkdir raspi
$ cd raspi
$ git clone https://github.com/raspberrypi/tools

PATHの設定

$ export PATH="$HOME/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian:$HOME/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin:$PATH"

ソースコード

$ git clone --depth=1 https://github.com/raspberrypi/linux

defconfig の作成 (Raspberry Pi 2)

$ cd linux
$ KERNEL=kernel7
$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig

カーネルのコンパイル
1時間くらいかかります

$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- zImage modules dtbs

SDカードへの書込み
SDカードのデバイス名を調べる

$ ls /dev/sd*
/dev/sda  /dev/sda1  /dev/sda2  /dev/sda5
/dev/sdb  /dev/sdb1  /dev/sdb2

SDカードのマウント

$ mkdir mnt
$ mkdir mnt/fat32
$ mkdir mnt/ext4
$ sudo mount /dev/sdb1 mnt/fat32
$ sudo mount /dev/sdb2 mnt/ext4

SDカードへの書込み

(ext4)
$ sudo make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=mnt/ext4 modules_install
(カーネルのバックアップ)
$ sudo cp -p mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
(fat32)
$ sudo scripts/mkknlimg arch/arm/boot/zImage mnt/fat32/$KERNEL.img
$ sudo cp arch/arm/boot/dts/*.dtb mnt/fat32/
$ sudo cp arch/arm/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
$ sudo cp arch/arm/boot/dts/overlays/README mnt/fat32/overlays/

SDカードのアンマウント

$ sudo umount mnt/fat32
$ sudo umount mnt/ext4

ラズパイでの確認
ラズパイにSDカードを挿して、電源を入れる。
無事にブートするかを確認する。
カーネル・バージョンを確認する。

$ uname -a
Linux raspberrypi 4.4.8-v7+ #1 SMP Tue Apr 26 01:16:11 JST 2016 armv7l GNU/Linux

2016-03-18-raspbian-jessie.img のカーネル・バージョン

Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux

参考
Raspberry Pi – KERNEL BUILDING
Raspberry Pi 2のカーネルをビルドしてみた


MAC で hello.c をARMバイナリにクロスコンパイルする


(1) Ubuntuの環境をつくる
MAC で Ubuntu を動かす (VirtualBox)

以降、Ubuntu環境です
(2) ARMの開発環境をインストールする

$ sudo apt-get install g++-arm-linux-gnueabihf

(3) hello.c をクロスコンパイルする
hello.c

#include <stdio.h>
int main(int argc, char *args[])
{
    printf("Hello, world!\n");
}

クロスコンパイルする

$ arm-linux-gnueabihf-gcc hello.c -o hello

実行すると、実行できないよというメッセージが出る

$ ./hello
bash: ./hello: cannot excute binary file:

(4) ARMの実行環境をインストールする

$ sudo apt-get install qemu-user qemu-user-static

環境設定する

$ update-binfmts --display qemu-arm
$ cd /lib/
$ sudo ln -s /usr/arm-linux-gnueabihf/lib/ld-linux-armhf.so.3 .
$ sudo ln -s /usr/arm-linux-gnueabihf/lib arm-linux-gnueabihf

実行すると、今度はOK

$ ./hello
Hello, world

(5) ラズパイで実行する
ラズパイに転送して、実行します。OKでした。

参考
Ubuntu 12.04 で hello.c をARMバイナリとしてコンパイルして実行してみる

debian – binfmt-support
binfmt_misc というカーネルモジュールは、システム管理者がファイル拡張子をベースにして各種バイナリ 形式をインタプリタに登録し、該当するファイルが実行された時には適切な インタプリタが呼び出されるようにできます。


VirtualBox ホストOSからゲストOSにアクセスする


ホストOSはMACで、からゲストOSはUbuntuです。

VirtualBox は初期状態では、NATに設定されています。
この状態では、ゲストOSからホストOSにアクセスできます。

$ ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=63 time=0.164 ms

ホストOSからゲストOSにアクセスするには、「ホストオンリーネットワーク」を追加します。
VirtualBox -> ゲストOSの設定 -> ネットワーク -> アダプタ2
20160420_virtualbox_host_only

ゲストOSにて、sshをインストールする。

$ sudo apt-get install ssh

ゲストOSにて、IPアドレスを調べる。

$ Ipconfig
enp0s8    Link encap:イーサネット  ハードウェアアドレス 08:00:27:d5:17:a1  
          inetアドレス:192.168.99.100  ブロードキャスト:192.168.99.255  マスク:255.255.255.0

ホストOSからアクセスする

$ ping 192.168.99.100
PING 192.168.99.100 (192.168.99.100): 56 data bytes
64 bytes from 192.168.99.100: icmp_seq=0 ttl=64 time=0.531 ms
$ ssh user@192.168.99.100
user@192.168.99.100's password: 
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64)

参考
VirtualBoxでホストOS<->ゲストOS間 ゲストOS->インターネット間の通信を行う方法
VirtualBox ネットワーク設定


ラズパイ USBカメラ (fswebcam)


fswebcam を使用して、ラズパイにUSBカメラを接続します。
fswebcam はシンプルなウェブカメラのアプリです。
V4L1/V4L2 互換のカメラから、画像をキャプチャして、PNG 形式または JPEG 形式に画像圧縮します。
ラズパイ公式サイトでも紹介されています
USING A STANDARD USB WEBCAM

インストール

$ sudo apt-get install fswebcam

使い方

$ fswebcam image.jpg

Buffalo BSW20KM15 は、上記では黒い画像になってしまいます。
下記のように、解像度の指定が必要でした。

$ fswebcam -r 1600x1200 image.jpg

20160317_fswebcam


ラズパイ USBカメラ (Motion)


Motion を使用して、ラズパイにUSBカメラを接続します。
Motion は、カメラからの映像信号を監視するプログラムです。
MJPG-streamer と異なり、画像に動きがあったときに、記録することができます。

インストール

$ sudo apt-get install motion

起動

$ motion -n
...
[0] [NTC] [ALL] motion_startup: Motion 3.2.12+git20140228 Started
cap.driver: "uvcvideo"
cap.card: "BUFFALO BSW20KM15 USB Camera"
...

表示画面
WEBブラウザでアクセスする

http://localhost:8081/

20160316_motion_control

設定画面
WEBブラウザでアクセスする

http://localhost:8080/

20160316_motion_stream

動きがあると、/var/lib/motion に画像が記録されます。

デーモン化して、外部から閲覧できるようにする

$ sudo nano /etc/motion/motion.conf
(デーモン化)
#daemon off
daemon on
...
(※ 外部から閲覧できるようにする)
#stream_localhost on
stream_localhost off

※ 以前のバージョンでは、webcam_localhost でした。

$ sudo nano /etc/default/motion
(デーモンを起動する)
#start_motion_daemon=no
start_motion_daemon=yes

起動

$ sudo service motion start

ドキュメント
MotionGuide

日本語で公開しているサイトもあります。
Motion の導入手順 ~ 指定した内容、パラメータの意味について

参考
[Raspberry Pi]motionでお手軽監視カメラをつくる
Raspberry Piと安めのウェブカメラで監視カメラを作る。何か動きがあったら画像保存もする
Webカメラを使ったライブ映像配信、監視、定点観測システム構築