ネトサバ日記

インフラに関する投稿をしていきます

Raspbeery Pi (jessie) 一般ユーザでのRPi.GPIO操作

Raspberry PiでGPIOいじって一般ユーザでGPIO制御しようとしたらエラーが出たのでそれの対処法

すぐに見つかってほしかったんだけど検索能力ないのか見つからなかったので備忘ログ


Raspberry PiでGPIOを扱う方法として色々あるけど代表としてシェルスクリプトPythonで扱う場合、まずGPIOのセットアップするのに次のようなコマンドor文を使う。

シェルスクリプト

$export GPIO番号 > /sys/class/gpio/export

Python

>>>from RPi import GPIO
>>>GPIO.setmode(GPIO.BOARD)
>>>GPIO.setup(GPIO番号, GPIO.IN)



ただpiユーザを使わず、一般ユーザの場合シェルでもPythonでもgpioグループを持っていないのでGPIOの書き込み権限がない。
なので失敗する。

じゃあユーザにgpioグループをつけようってことで以下のコマンド打ち込み。

$sudo gpassword -a ユーザ名 gpio

これでイケルと思ったらシェルスクリプトでは使えたのにPythonでは使えない。
エラー内容見ると
    GPIO.setup(self.sensor_port, GPIO.IN)
RuntimeError: No access to /dev/mem.  Try running as root!
GPIOハードウェアにアクセスするのに仮想メモリ使ってるっぽいんだけどそれにroot以外はアクセス出来ないみたい。
いや、rootでは動かしたくないんです...


それで調べてみると/dev/memと/dev/gpiomemってのがあって/dev/memはroot必須みたいだけど/dev/gpiomemは書き込み権限さえあれば書き込めるらしい。

なんで、

$sudo chown root:gpio /dev/gpiomem
$sudo chmod 660 /dev/gpiomem

これを起動時に自動で実行してもらうために
/etc/rc.localに書き込んで再起動。

これで実行できる。

せめてGPIO用のメモリを作ってるんだったらグループの書き込み権限つけといて欲しい。


参考
http://decafish.blog.so-net.ne.jp/2015-08-27
https://tool-lab.com/make/raspberrypi-startup-24/
http://a244.hateblo.jp/entry/2016/11/10/063000

オレオレ証明書の有効化

久々にブログを書きたくなったので最近自宅サーバのオレオレ認証局を作りなおしたのでそのときのルート証明書の更新方法を備忘録として書きます。


今回、以下の3環境で更新
ついでに認証局DebianでCA.shを使って作成してWindows用にderに変換してWebのあるページを叩いたらダウンロードできるようにした。

Windows 10

  1. derファイルに変換したものをダウンロード
  2. 証明書を開いて「証明書のインストール」
  3. 保存場所はどちらでもいいので次の証明書ストアの場所を「信頼されたルート証明書」にする
  4. ブラウザを再起動すると証明書が読み込まれる
ただし、Firefoxは個別でルート証明書を管理しているので別に対応しないといけない。けど割愛

Debian 8

Linuxは基本的には「update-ca-certificates」コマンドを使ってルート証明書をロードする。
Debianでは/usr/local/share/ca-certificatesと/usr/share/ca-certificatesに保存する場所がある。
この2つは役割が違っていて/usr/shareの方は/etc/ca-certificates.confで記述したファイルの.crtファイルのみ読み込まれる。
/usr/local/shareはそこに置かれた.crtファイルすべてが読み込まれる。
読み込まれると/etc/ssl/certsにリンクされる。
なので、設定方法は
  1. 証明書の拡張子を.crtに変更
  2. /usr/local/share/ca-certificatesフォルダ内にコピーする
  3. update-ca-certificates実行

CentOS 7

Debianと違って/etc/pki/ca-trust/source内の証明書を「update-ca-trust」コマンドで一つにまとめられる。
まとめられる先は/etc/pki/tls/certs/ca-bundle.crtになる
  1. 証明書を/etc/pki/ca-trust/source/anchorsにコピー
  2. update-ca-trust extract実行

openssl系のコマンドはややこしい...

FreeRADIUSでのアカウンティングエラー:Error: [sql] Couldn't insert SQL accounting START record - Duplicate entry 'xxxx' for key 'acctuniqueid'

研究室の無線LAN認証で使っているRADIUSサーバで時々アカウンティングのログが失敗してて
うちでは、研究室の在室状況をアカウンティングで見ているのでいやだなぁと思いながらトラブルシューティング

エラー内容は/var/log/freeradius/radius.logで
Error: [sql] Couldn't insert SQL accounting START record - Duplicate entry 'xxxxx' for key 'acctuniqueid'
となって実際にMySQLには書き込まれていない状況。。。


この'acctuniquid'はRADIUSクライアントが作っていると思っていたけどそうじゃなくてFreeRADIUSが作ってるフィールドみたいで、これがRADIUSサーバ上でのセッションを管理するキーになってるみたい。
だから、MySQLスキーマ変更して'acctuniqueid'をユニークキーじゃなくしてしまえーってすると機能しなくなりますので、絶対にやめて下さい。

設定を見てみると

となっており、
User-Name, Acct-Session-Id, NAS-IP-Address, NAS-Identifier, NAS-Port
で構成されているようです。
この中でユーザ情報、NASの情報は重複が必ず考えられるので
Acct-Session-Idが重複がないようにしないといけないみたい。

んで、Acct-Session-IdはクライアントがCisco 1200シリーズの場合だと
デフォルトでは、
'00000001'とか'00000002'とかって順番に振られているだけでクライアントが再起動しちゃうと
また'00000000'から振り直しになって結果的に'acctuniqueid'も重複してるみたい。

んで、調べてみたら
http://www.cisco.com/cisco/web/support/JP/docs/CIAN/IOS/IOS15_1S/CG/023/sec_rad_56bit_supp.html?bid=0900e4b18252981d
ここで書いている通り
56ビットのAcct-Session-Id+リブート時にインクリメントされる8ビット=最大255回の再起動までのユニークなIDが振れるよってことになる。

なので、Aironetで
radius-server unique-ident 0
とすると前までAcct-Session-Idとして振られていた32ビットに加えて
リブート回数を記録しておく先頭8ビットをもった32ビットが追加され
255回まで再起動可能の
一回の再起動で56ビット=2^56-1回のアカウンティングパケットがユニークIDとして記録できるようになります。




ということで
これで、まあ研究室で使う分には大丈夫なんじゃないかな?

Chinachuをリバースプロキシしてサブディレクトリで公開する

年末年始にちょっと前に組み立てた録画サーバに色々と助けられて
色々と問題を残してくれたのでそれについて備忘録的に投稿

というか、留学から帰って一番にしたことがサーバの再構築って...

Chinachuいいですよね。コミュニティも色々な意味でホットになっていますし^^;

入りたいとは思うけど技術的にそのレベルに達していないから低い位置からCommitをwktkしながら待っています。

Chichu Airも遅れながら進んでいるようですし


そんな、Chinachuですが2016/01/14時点でStableバージョンでは
192.168.1.2/chinachu/
にアクセスしてnginxなどでリバースプロキシをかけて
Chinachu本体の
192.168.1.2:10772
にアクセスすることはできるんですが、ストリーミング視聴すると
XSPFファイルのlocationではサブディレクトリが考慮されていないので
視聴できないと言われます。

これは、開発版では治っているんですけど安定版ではまだ修正されていないので
パッチをあてないといけないです。

内容的には、web/page/programとweb/page/channel内のwatch.jsの数行を変えてあげるだけなのでそれだけで修正できます^^

というか、ここで言われている行を変えるだけですけど

patchファイルとしては先ほど2箇所のwatch.jsに
patch -u watch.js < 'patchファイル'
としてあげるだけです。
パッチファイルは次の2つ

Program用

Channel用

もうひとつ、リバースプロキシをかけると接続の始まりで時間をかけているなと思ったら
proxyでWebSocketを使うために
ヘッダーを書き換えないといけないとかで次のように書き換え


これで無事設定完了

スリープ状態の解除元: 不明の原因

Windows 8.1にしてぐらいからどうもスリープしても勝手に解除されることが多く
特に最近ファンの音がうるさくなってきたので
原因を探って解決して快眠できて嬉しかったので久々に投稿笑


コンピュータの管理からイベントビューアで
スリープ解除の原因を探ろうと思ったけど下のようにスリープ解除元が不明と出てここからは原因がわからなかった。


マウスとキーボードがバッファローの無線のものだったのでそれが悪さしてるのかなと思って
バイスマネージャーからマウスとキーボードとネットワークからスリープ解除できないようにしても
また、勝手にスリープしたのでこれは、調べないと無理かなと思って
powercfgのコマンド調べてたらタイマー情報を取得できるコマンド
「powercfg -waketimers」があったので実行してみると原因判明!

  Reason: Windows は、スリープ状態の解除を要求したスケジュールされたタスク
'NT TASK\Remediation\AntimalwareMigrationTask' を実行します。

とあったので調べてみたらNortonの設定やライセンス情報の確認・移行?で30分に一回
スリープ解除してでも実行しているみたいでした。

そんなに、確認しなくても...と思わなくもないですが^^;

てことで、
タスクスケジューラで上のタスクを探して
条件タブの「タスクを実行するためにスリープを解除する」のチェックを外したらok。

これでうるさいファン音から開放されて朝まで快眠できるね。やったね。

ラズベリーパイ再構築 その2

SDカードをFAT32でフォーマットして
NOOBSをインストール

raspbianのインストールを完了して

piユーザの削除、管理者ユーザ追加

rpi-updateとyum updateを終わらせた状態からスタート!


/tmpなどのディレクトリをtmpfsにする

# vi /etc/fstab
# 以下3行追加<
tmpfs /tmp tmpfs defaults,size=128m,noatime,mode=1777 0 0
tmpfs /var/tmp tmpfs defaults,size=32m,noatime,mode=1777 0 0
tmpfs /var/log tmpfs defaults,size=32m,noatime,mode=0755 0 0

/tmpディレクトリは後々motionで撮影した動画を一時的に保存しておく予定なので128MB確保しておく
あとは/var/tmpは全く使われているのを見たことがないけど一応32MB
/var/logもこれからrsyslogのログをほとんど止めるので32MBぐらいでもokかと

とりあえずこれで再起動すれば3つのディレクトリがメモリ上に配置されてSDカードにアクセスせずにすみます
ついでにベンチマークもとってみたけど書き込み速度は0だけ書き込んでたからかもしれないけどSDカードでも思ったよりスピードが早かったことにびっくりした
あとtmpfsのデバイス名がわからんかったからそれっぽい/dev/ram0を使ってみたけどあってるんだろうか?

# df
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
rootfs 14048320 3730792 9580864 29% /
/dev/root 14048320 3730792 9580864 29% /
devtmpfs 470400 0 470400 0% /dev
tmpfs 94940 272 94668 1% /run
tmpfs 5120 0 5120 0% /run/lock
tmpfs 189860 0 189860 0% /run/shm
/dev/mmcblk0p5 61302 19550 41752 32% /boot
tmpfs 131072 20248 110824 16% /tmp
tmpfs 32768 0 32768 0% /var/tmp
tmpfs 32768 216 32552 1% /var/log

#ビフォー
# hdparm -t /dev/mmcblk0p5

/dev/mmcblk0p5:
Timing buffered disk reads: 52 MB in 3.01 seconds = 17.30 MB/sec
100+0 レコード入力
100+0 レコード出力
104857600 バイト (105 MB) コピーされました、 1.01872 秒、 103 MB/秒

# アフター
# hdparm -t /dev/ram0

/dev/ram0:
Timing buffered disk reads: 4 MB in 0.02 seconds = 175.70 MB/sec
# dd if=/dev/zero of=/tmp/test.tmp ibs=1M obs=1M count=100
100+0 レコード入力
100+0 レコード出力
104857600 バイト (105 MB) コピーされました、 0.54684 秒、 192 MB/秒

これによってログや一時ファイルの保存のせいでSDカードがお仕事しなくても良くなった
ほかのサイトではスワップ容量を0にしてSDカードに全く書き込みを起こさせないようにしてたけどtmpfsの仕様で予約メモリを超えた時にスワップを使うようにするらしいので保険のために逆にスワップ容量追加

# vi /etc/dphys-swapfile
CONF_SWAPSIZE=1000
さらにラズパイ起動時に/var/logファイルが何もない状態ではエラーが起きてしまうので rc.localに以下記述

# vi /etc/rc.local
# 起動時、自動的にディレクトリを作成
mkdir -p /var/log/ConsoleKit
mkdir -p /var/log/samba
mkdir -p /var/log/fsck
mkdir -p /var/log/apt
mkdir -p /var/log/ntpstats
chown root.ntp /var/log/ntpstats
chown root.adm /var/log/samba

# 起動時、自動的にLastlogとwtmp,btmpファイルの空ファイルを作成
touch /var/log/lastlog
touch /var/log/wtmp
touch /var/log/btmp
chown root.utmp /var/log/lastlog
chown root.utmp /var/log/wtmp
chown root.utmp /var/log/btmp
あとは/etc/rsyslog.confでログ出力したくない項目をコメントアウトして終了 次はmotionの設定

ラズベリーパイ再構築 その1

お久しぶりです


以前買ったRaspberry Pi 2Bですが
車監視用監視カメラとUSBRHでの温度計測のために使っていました。
その時の私はまだSDカードに絶対の信頼をおいていました
がある日監視カメラを見ようと思ったら応答なし...
pingも応答なしでHDMIで直接起動してみたら

recovery required on readonly filesystem ext4 raspberry
どうやら、SDカード使いまくって書き込み可能回数をゆうに超えていたみたいです
まあそりゃ毎分温度記録して監視カメラも録画してたらそうなるか...
とりあえず、中の設定ファイルとかスクリプトとかチョメチョメとかをサルベージしようと思ったけどまずSDカードが認識できなくて諦め

ってことで新しいSDカード買ってまたラズベリーパイ構築しなおしたいと思います
要件としては
  • /tmp, /var/tmp, /var/log ディレクトリをtmpfsにしてSDカードへの書き込みをなくす
  • rsyslogのログ出力を減らす
  • USBRHの温度データを母艦鯖のmysqlSSLで記録
  • 監視カメラの動画は30分かごとに母艦鯖にSCPで移動

SDカードはTOSHIBAの16GBをamazonから購入
NOOBSからRaspbianをインストール、
yum updateとrpi-updateをした状態で
SDカードの負荷を下げる作業
これは次の記事で紹介したいと思います