それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

git lfs でバイナリファイルをバージョン管理できるようにする

git レポジトリに大きめのファイルを突っ込みたい。

動画の素材ファイルや、画像の素材ファイルとか、Sketch とか figma のデータそのままとか、コンパイルしたExecをそのままとか、考えるの面倒くさいのでどっかに放り込んでいきたい。

google drive に放り込んでいたけど、バージョン管理に時間制限があって、30日前になる。かといってDropboxまで追加で契約すのも面倒くさい。Evernoteは添付ファイルに容量制限があるし。

git lfs でバイナリ用のバージョン管理をする。

git lfs がありまして、 git large file storage の略ですね。比較的大きめのファイルをまとめてツッコんでgit と連携させることが出来る github製のツールです。

github 以外でも bitbucketや gitlab で利用できます。

f:id:takuya_1st:20180103205002p:plain

使い方:クライアント

大きめのファイルをツッコんだら自動的にGit LFS になる。なんてことはない。このファイルはLFS管理しますよって設定が必要

なので、最初に このコマンドを突っ込む

git lfs install 

lfs のインストール

といっても、git lfs は git に同梱されておらず。別途インストールが必要。

brew install git-lfs

はじめの一歩

git lfs をインストール後に、レポジトリでlfs を有効にする、対象の拡張子を指定し設定する。そしてgitattributesを追加してcommit する。

git clone URL
cd REPO
git lfs install                #
git lfs track '*.psd'     # ここがlfs 特有の箇所
git add .gitattributes  #
git commit -m 'my commit comment'
git push origin master

git lfs install でlfs 初期設定

lfs install すると .git ディレクトリ内部に、lfs の管理フォルダが生成される

takuya@sample001$ find  .git/
/Users/takuya/.bin/find .git/ -mindepth 1 -not -iwholename '*/.git/*'
.git/config
.git/description
.git/HEAD
.git/info
.git/info/exclude
## ↓この辺が作られる
.git/lfs
.git/lfs/objects
.git/lfs/objects/logs
.git/lfs/tmp
.git/lfs/tmp/objects
.git/objects
.git/objects/info
.git/objects/pack
.git/refs
.git/refs/heads
.git/refs/tags

git lfs track でLFSの管理にするファイルのパターンをしてい、その設定が gitattributeに記述されるので、それを追加する。

git lfs track '*.rar' をした場合

gitattributes ファイルに、どのファイルをLFS対象にするか設定が書かれる。

takuya@sample001$ grep rar -R   .
./.gitattributes:1:*.rar filter=lfs diff=lfs merge=lfs -text

すでに設定があるので、重複したtrackも検出される。

takuya@sample001$ git lfs track '*.rar'
"*.rar" already supported

あとは commit

gitattributes も忘れずにコミットしないとね。

gitlab の場合

gitlab で git lfs を使う場合は、 lfs.url を追加しておく必要があった

git clone URL
cd REPO
git lfs install                
git config --add lfs.url https://example.com/takuya/sample01.git/info/lfs
git lfs track '*.psd'     
git add .gitattributes  
git commit -m 'my commit comment'
git push origin master

git lab のレポジトリURLの末尾に、 reponame.git/info/lfs を加えたものを追加した。

gitlab 側の設定

omni gitlab CE側では LFSを受け取れるように設定する必要があった。

### Git LFS
gitlab_rails['lfs_enabled'] = true
gitlab_rails['lfs_storage_path'] = "/var/opt/gitlab-lfs" 

lfs_storage_pathは自分で指定しておく必要がある。 reconfigure した時に、生成されパーミッションが設定された。

LargeFileが入ってくるところなので、それなりに安心して置いて置ける場所がいいと思う。

ディレクトリ設定に注意が必要だった。 ディレクトリは、gitlab レポジトリと別に設定できるので、管理対象として認識する必要がある。

ディレクトリを追加してるので、バックアップや移動時やDocker起動してるときに面倒だな

2018-01-03 追記

git config --add lfs.url は無くても動いた。

アイティメディアIDがパスワード12文字以下

アイティメディアIDを登録したらこんなことに。

f:id:takuya_1st:20171228144225p:plain

なぜ、パスワード文字数の上限が在るんでしょうか。

  • パスワード文字数の上限が在る
  • → 固定長でデータベースが設計されてる
  • → → AESかなにかでEncryptするなど原文まま保存している

つまり、ハッシュ化してないんじゃないかと。最近多いのかなぁ。パスワードといえばハッシュだと信じてた私が間違ってるんでしょうか?

rclone コマンドで google ドライブにデータを転送する(rcloneインストール方法と使い方)

rclone コマンドが便利

rclone コマンドは、各種のストレージサービス間でデータの転送が出来るように設計されたクライアントコマンド。

rclone は数多のクラウドと連携してクラウド間でデータ転送を行うことが出来て、各種サービスのフロントエンドプログラムを個別にインストールしなくてもまとめて使えるのでとても便利。

rclone で出来ること

強いよね。

対応してるクラウド

メジャーなものはたいてい対応してる

SFTPとowncloud サポートが在るので、rclone 使っててクラウド料金が嵩んだとして、自鯖で生き残れそうですね。

rclone のインストール

macOS / OS X

brew install rclone

debian

sudo apt install rclone

ubuntu server には apt パックに rclone がなかった

ubuntu などその他

curl https://rclone.org/install.sh | sudo bash

rclone を使ってみる

リモート設定をするのはちょっとあとにして、まずは使ってみる

rclone sync ~/Desktop/sample ~/Desktop/backup
rclone copy  ~/Desktop/sample.txt ~/Desktop/copied.txt

ローカルで使えることがわかった。

google driveにアクセス設定をする

google drive にアクセするには2つの手順が必要

  • rclone をOAUTH クライアントとして設定
  • Driveのアクセス権限を rclone にOAuthで渡す。

rclone に oauth クライアントIDを設定

GoogleAPI Consoleにログインして

  • 新規プロジェクト作成
  • 作ったプロジェクトで Google drive api を有効にする。
  • 作ったプロジェクトのoauthクライアントIDを作る
  • 作ったプロジェクトのoauthシークレットを取り出す。

つまり、誰のGoogle アカウントのAPI権限で rclone を動かすのかって言う設定ですね。

create credentials で oauth client を選べばおっけ

f:id:takuya_1st:20171227202056p:plain:w400

google drive の許可設定

つぎに、アクセスしたい google drive のオーナーから 、 rclone に許可を出す必要がある。

rclone に google drive を設定する。

rclone config コマンドで、新規作成する。

takuya@~$ rclone config

e) Edit existing remote
n) New remote
d) Delete remote
r) Rename remote
c) Copy remote
s) Set configuration password
q) Quit config
e/n/d/r/c/s/q>

クライアントのIDとシークレットをいれる。

rclone をどのプロジェクトとして動かすかの先程設定したクライアントIDを設定して決定する

Storage> 9
Google Application Client Id - leave blank normally.
client_id> lrgchkfmyhsdr7ey
Google Application Client Secret - leave blank normally.
client_secret> uzhjqwosqs9zgxqa

空白でもいいっていうメッセージが出て来るが、これを空白にすると、403 Rate Limite Exceeded で苦しむことになる。端的に言うと、rclone を使ういろいろな人と クライアントIDを共有するので、転送上限も共有することとなって、上限になっちゃうよってことでしょうね。→ https://github.com/ncw/rclone/issues/1591

OAuthでrclone Drive のアクセス権限を渡す。

最後に、 OAuth して、ブラウザが起動されるので、「使いたいドライブのオーナー」としてログインして、rclone にアクセス権限を渡す。

ブラウザ経由のOAuthの権限委譲の、この処理が挟まるので、出来る限りサーバや仮想マシンや docker イメージで rclone を設定せずにデスクトップの端末でrclone を初期設定するべき。楽だからね。

設定まとめ。

「rclone が、誰のAPIアクセスとして、誰のドライブを扱うのか」です。

登場人物は3つ、

  • rclone (アプリ
  • API IDの保持者
  • ドライブの保持者

ですね。

設定ファイルのコピーと移動

設定ファイルは次の場所に保存される。

~/.config/rclone/rclone.conf

このファイルの中に、クライアントIDとOAuthのアクセストークンが入ってるので厳重に管理する。

このファイルをコピーすれば、別のパソコンやサーバーで設定しなくても同じ設定が使えるようになる。

rclone の設定一覧

rclone でいまどのクラウド・ドライブを設定しているか一覧を見るにはこれ。

rclone listremotes

rclone でGoogle Driveのフォルダを見る

rclone lsd myDrive:
rclone lsd myDrive:/ #または

rclone でGoogle Driveの最上位ディレクトリを見ることが出来る。

rclone で 特定のフォルダの中を見てみる

rclone ls myDrive:/name/to/my/forlder

フォルダの名前でアクセスできるから便利!

rclone で同期する

sync で同期する

## dry-run
rclone sync -n /path/to/my/folder  myDrive:/name/to/my/forlder
## not dry-run
rclone sync  /path/to/my/folder  myDrive:/name/to/my/forlder

sync するとローカルに無くて、リモートに在るファイルは「削除」されるので手作業で試すときはかならず -n をつけること

同期の書き方

rclone sync  SRC DST

同期するときは SRC のファイルがDSTに転送される。SRCとDSTが絶対に同じ状態になる。

  • SRC になくて、DSTにだけ在るファイルは削除される。
  • DST になくて、SRCにだけあるファイルは新規作成される。
  • SRC と DST でサイズが異なり、日付が違うファイルは SRCに合わせる。

オプションをつけないと結構ガンガン消されたり更新されるので注意が必要

日付があてにならないときは md5 などハッシュで当てることも出来る。遅いからやらないけど。

google driveのバージョン管理は???

次のキャプチャが、sync でローカルの更新ファイルをGoogle Driveにコピーした例。

ちゃんと、Google Driveのバージョン管理(旧版)として認識されている。

f:id:takuya_1st:20171227204437p:plain

表示を少なくしたいとき

quiet な表示には -q オプションで行ける

自動実行なんかはコレで楽になるよね。

転送量について

ちゃんとクライアントIDを設定しても 403 User Rate Limit Exceededが出て来ることがある。複数台で一度に転送しようとすると出てくることがある。ちゃんとクライアントIDを分けてドライブのアクセス上限にかからないようにしたほうがいい。

フォルダが存在しないときはどうなるの

rclone sync  /path/to/my/folder  myDrive:/name/to/my/no_exists_foldername

存在しないフォルダ名を指定したら、そのフォルダが作成されて、その中にファイルが放り込まれる。上手に使えば毎月のアーカイブを作れる。

ただし、バックアップのログだけはきっちり見ておきましょう。 転送量上限に掛かってエラーになったりするんで

その他のツール

rclone の他にも google drive をぱぱっと使えるコマンドは結構ある。

FUSEでマウントする系もあるんだけど、遅いから使うのやめちゃった。

FUSEマウントより、fsevent/ inotify でファイルシステムの変更イベントでデータ同期したほうが楽だし速いしね。

進捗状況を表示する。

rclone でも wgetrsync のように show progress オプションがああれば手作業で扱うときに、データ転送のETA(残り時間)や転送済みのバイト数を表示できたら便利。転送のパーセント表示をしたいなとおもってたら、オプションができてた。

root@rclone:~# /usr/bin/rclone --config /root/.config/rclone/rclone.conf --progress --stats-one-line sync  gitlab:/var/opt/gitlab/backups  gdp:/server/gitlab-backups
400M / 43.740 GBytes, 1%, 12.516 MBytes/s, ETA 59m6s

--progress --stats-one-line sync をオプションにつければ、転送状況をモニタリングできてるのである。

Google Driveへのアップロードは、MAXで15Mbps程度、平均しても 10Mbps 程度しか出ないので、残り時間を見るのがとても大事。

濫用は禁物

OneDriveもAmazon DriveもDropboxもみんなが乱用して、容量制限ができたり値上げされたりしたので、ほどほどに使ったほうがいいですよ。

みんながガンガン使うと結局は料金プランが値上がりして損をしますから。とくに学生の方々は、無料だからと言って数10TBとか使うとたぶん無料プランなくなるのでほんとうに程々に使いましょうね。

バックアップに使うと便利なんだけど、ご利用は計画的にね。

2018-07-18

記述修正

2020-07-31

転送のモニタリングについて追記。

参考資料

Rclone started returning errors after uploading at most 800gb · Issue #1591 · rclone/rclone · GitHub

Rapiをリモコン操作して、omxplayer をTVのリモコンで操作する。

この記事は Raspberry Pi Advent Calendar 2017 にあわせて書きました。

https://qiita.com/advent-calendar/2017/raspberry-pi

Raspberry Pi をTVのリモコンで操作する。

最近、Raspi で 動画を見てるんですよ。AppleTVやChromeCastやFireTVもあるんだけど、不自由なOSより自由にカスタマイズ出来るやつがやっぱり嬉しい。

Raspi は リモコンで操作するが出来る

これも以前試したんだけど、KODIならリモコンで操作が出来るんですね。

takuya-1st.hatenablog.jp

リモコンの操作をもっと自由に割当てたい。

TVのリモコンはもっと自由に使えたら良いんでですよ。

cec を使えば、TVのリモコンから信号が送れるよ!

f:id:takuya_1st:20171227172117p:plain

sudo aptitude install cec-utils 

CECでRaspi→テレビに命令を送る

cec で使う信号は HDMI を通信ケーブルとして、各種のリンク機構が実現できる。よくビエラリンクだとかファミリリンク機能とか家電メーカーが勝手に名前つけてるアレですね。

テレビ電源をオンにするには

echo 'on 0' | cec-client -s 

Raspi 側からテレビに信号を送ることが出来る。今回のエントリはでは、テレビ側からRaspiに信号を送ります。

CECからテレビ→Raspiに命令を送る

通信なんだから、当然逆もできるよね?

Raspi でテレビのリモコンのボタンを受取りする

raspi のSSHにログインして、ターミナルをあけておきます。 そして、おもむろに クライアントを起動します。もちろんTVとHDMI接続をしている前提です。PC用LCDはCEC非対応なので無理です。

$ cec-client

TVのリモコンからボタンをいろいろと押してみます。

すると、テレビのリモコンの押されたボタンが、PRESS/UPなどで表示されるはずです。

TV側でリモコンの連携を設定をしてなければ、上・下・左・右・OK・キャンセル・一時停止くらいでしょうか。

テレビ側で、Raspiの繋がってるHDMIポートをHDDレコーダーとして設定してあげれば、リモコンのチャンネル番号ボタンなども取得できます。

これを強引に監視します。

ほんとうは libcec を使ったプログラミングをしたほうがいいでしょう。 ちゃんとボタンの押下(down)・押上(up)・長押し(press)を取得すれば良いんだろう

けど面倒くさいので、純化してコンソールの出力を監視します。

仕組みは?こういうことです。

仕組み1:cec-client のデバッグメッセージを監視する

DEBUG:   [            5443] >> TV (0) -> Recorder 1 (1): user control pressed (44) # ←これを取得してgrep でマッチさせる
TRAFFIC: [            5576] >> 01:8b:03
DEBUG:   [            5576] key released: left (3)
DEBUG:   [            5577] >> TV (0) -> Recorder 1 (1): vendor remote button up (8B)
TRAFFIC: [            5918] >> 01:44:03

仕組み2:押されたボタンをgrepで強引に取得する。

cec-client のデバッグメッセージを監視、 正規表現で押されたボタンを抜き出します

cec-client | grep --line-buffered -Po '(?<=key pressed: )\w+(?= \(\d, \d\)$)'

仕組み3:ボタンがわかればSwitch/CASE文で何かする。

指定したメッセージが来たら、プログラムにメッセージを送ります。

1行ずつ読み込んで、ボタンが押されたら、なにか関数を実行します。

function onright(){
  #「 →:右ボタン」が押されたときの動作
}
## 略
while (略) do 
case button in
        right) onright;;
        left) onleft;;
        down) ondown;;
        up) onup;;
        select) onselect;;
        play) onplay;;
        pause) onpause;;
        forward) onforward;;
        backward) onbackward;;
        exit) onexit;;
        clear) onclear;;
        *) echo "unrecognized button ($cmd)";;
esac
done;

実際にやってみる。

だいたい仕組みを考えたところで、TVリモコンの信号を受けてみます。

bashシェルスクリプトで試してみます。

cec-watcher.sh

button_filter() {
  \grep --line-buffered -Po '(?<=key pressed: )\w+(?= \(\d, \d\)$)'
}

echo as | cec-client | button_filter | \
while read cmd; do
  echo $cmd;
done

出来たら実行してみる。

実行し、リモコンを押してみると!

$ bash cec-watcher.sh
right
left
down
up
pause
right
right

おおお、ボタンが表示されたよ!

ここまできたら、好きな機能を割当てたい

テレビ側に繋いでいたら、好きな機能をリモコンから呼び出すことが出来ますよね?

たとえば、1押したら、Radiko起動したり、2押したら音声認識が起動してスマート・スピーカーにするとか、3押したらメールを送るとか

なんでもできそうです。

omplayer の制御をする。

omxplayer は raspi でよく使われるプレイヤーです。とても便利です。

御存知の通り omxplayer はキーボードから制御ができます。→ raspberryPi でMP4動画の快適再生するコマンド omxplayer とその使い方(キーボード操作 - それマグで!

omxplayer をコマンドから制御する

omxplayer の標準入力は tty の stdin につながってるので、これを適当なFIFOに繋いであげれば、コマンドから制御ができます。

fifo を作る

mkfifo /tmp/omx-input

omxplayer が fifo から読み込むようにする

omxplayer URL < /tmp/omx-input

omxplayer を遠隔から操作する

p ボタンは再生・一時停止なので、これを送ってあげたら再生停止が出来るようになります。やったね!

echo -ne p > /tmp/omx-input
echo -ne p > /tmp/omx-input
echo -ne p > /tmp/omx-input

FIFOとomxplayer のペアと、TVリモコンを取得する仕組みと組み合わせる

omxplayer を起動後に、テレビリモコンから、FIFO に文字を送るように組み合わせてあげれば、omxlayer が FIFO から文字を読み込んで再生・停止早送りをしてくれるようになるのです。やったね!これで制御できるね。

しかもバイナリも出てこないしCライブラリも無い、完全にUNIXのパイプと文字で構成されてる。楽ちんだね。

つまり、このようなコードを書きます

function onright(){
  # →が押されたときの動作
}
function onplay(){
  # play が押されたときの動作
}
## 略
while (略) do 
case button in
        right) onright;;
        play) onplay;;
        *) echo "unrecognized button ($cmd)";;
esac
done;

サンプルコード

上記の例を、実際に少し書き加えて動くようなった例です。

omxp-with-cec.sh

このコードのなかでは、 FIFO/tmp/cmd としています。 gist.github.com

起動

同動画を再生します。

$omxplayer  --hw -o hdmi $URL < /tmp/cmd

別シェルで、リモコンを監視します。

$ bash omxp-with-cec.sh

これで、再生ボタンかOKボタンを押すと再生が始まります!!!!!!!!!!!楽しい

これをPythonのコードにします。

ここまでだと、mkfifo を使って出力を取得しているだけなので、これは単純にパイプ化して、python の subprocess でプロセス制御とSTDIOの監視をしてやれば、完全にリモコンだけで制御出来るようになりますね

Cecを強引に使うクライアント書いたよ!

gist.github.com

omxplayerとCECラッピングしたもの

書いたよ ごめんなさい、時間無くて作れてません。 年末年始で作るのでよろしくお願いします。

python のsubprocessでomxplayer をテレビリモコンから使うやつ

gist.github.com

github にレポジトリ作った

https://github.com/takuya/omxplayer-with-tvremote

まとめ

RaspiをHDMIでテレビと繋いでると、テレビのリモコンでRaspiを操作できる。

どのボタンが押されてるか取得できる。

押されたボタンによって、起動するコマンドを変えて遊べる。

動画再生と組合せるとメッチャ便利。

組合せは使う人の発想次第でいくらでも、可能性は無限大。自由なソフトウェアは素晴らしい!!!

更新

2018-01-03 作りました

2018/01/03 github にレポジトリ作った

tcpdump で IPv6 のping(icmp)を取り出す

tcpdumpipv6 を取り出すには

tcpdump -v ip6

これで、IPv6のパケットを見ることができる。

tcpdump6 とかあるんかと、一瞬考えたけど、TCPTCPだし、IPレイヤは別だもんね。

tcpdump で ping6 のパケットを取り出す。

明示的に、icmp じゃなくて icmp6 を使う。

$ sudo tcpdump icmp6
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
03:55:58.371580 IP6 ::1:6203:8ff:fea1:820c > ::1:ba27:ebff:feac:e381: ICMP6, echo request, seq 22, length 16

ping6 だし、tcpdump6 かな?と一瞬思ったけど、 tcptcp なのでv6 じゃないよねと思った。

2019-01-08

若干更新

iptablesで224.0.0.251のApple Bonjour で通信ができなかった問題を解決した

224.0.0.251 のパケットまで止まってしまった。

iptables を設定したら、 ホスト名でSSHができなくなった。

sshできなかったので、最初は、iptablesssh を止めてしまったのかと青ざめたけど、ログを見たら224.0.0.251 宛のパケットが来てた。コレなんだと思ったらBonjourIPアドレスだった

Bonjour をdig コマンドラインから使う。

Bonjour の名前解決を、dig コマンドラインから行ってみる。

takuya@~$ dig +short raspi3.local. @224.0.0.251 -p 5353
192.168.20.3

iptablesBonjour のパケットを通してあげる。

dig でパケットの仕組みが少しわかったので、この仕組みを使って、iptablesを設定したRaspberry Pi に設定してあげる。

-A INPUT -p udp -m udp --dport 5353 -j ACCEPT

Bonjourあると便利だと思っていた、なるほどこうなってるのか。

参考資料

Netatalk - ArchWiki

mDNS を使いローカルマシン内の仮想環境に接続する - 破棄されたブログ

デスクトップの切替コマンドにbash completion を作った

以前、デスクトップの切替コマンドを作った

git stash 的に、デスクトップをスパッと片付けて、次の仕事に移りたいなって。

ユーザー切替でもいいのだけれど、デスクトップを切り替えておけば作業中ファイルをすべてデスクトップに散らかしてしまえば管理が楽だしね。

ただ、デスクトップの切替が不便だったので completion かいておいた

以前作ったコマンドについて

takuya-1st.hatenablog.jp

上記のコマンドのcompeltion がこれ

completion だけど、結構汎用的に書いておいたので何にでも使えると思う。

gist.github.com

切替コマンドで頭を切り替える。

デスクトップを切り替えると頭が切り替わる。

色々を切り替えると頭がスッキリするよね。

ブラウザにもこういう機能欲しいなぁ。

ブラウザをプライベートタブで開くように、ブラウザも作業毎にワークスペースほしいよね。

むかしはOperaにあったんだけどなぁ。Vivalidiにもあるといいな。

参考資料

http://takuya-1st.hatenablog.jp/entry/2016/02/10/175604

http://d.hatena.ne.jp/snaka72/20090930/1254316751

completion で決定後にスペースをいれる方法

https://stackoverflow.com/questions/2339246/add-spaces-to-the-end-of-some-bash-autocomplete-options-but-not-to-others

ssh をiptablesで国内限定にする(日本国外のIPから規制する)

グローバルIPssh を有効にしたらスキャンがいっぱい来る

別に、実害は無いんだけど、ちょっと気持ち悪いよね。 1時間で1000近いログが溜まるんですね。

ポート22のsshはすげぇアクセス来るんだよね。

ISP側である程度のフィルタをされているはずなんだけど。それでもコレくらい来る。

Dec 21 15:02:13 raspi3 sshd[3524]: Received disconnect from 115.238.245.2 port 33445:11:  [preauth]
Dec 21 15:02:13 raspi3 sshd[3524]: Disconnected from 115.238.245.2 port 33445 [preauth]
Dec 21 15:03:49 raspi3 sshd[3532]: Received disconnect from 115.238.245.6 port 34296:11:  [preauth]
Dec 21 15:03:49 raspi3 sshd[3532]: Disconnected from 115.238.245.6 port 34296 [preauth]
Dec 21 15:04:34 raspi3 sshd[3537]: Received disconnect from 221.194.47.245 port 57877:11:  [preauth]
Dec 21 15:04:34 raspi3 sshd[3537]: Disconnected from 221.194.47.245 port 57877 [preauth]
Dec 21 15:05:40 raspi3 sshd[3542]: Received disconnect from 221.194.47.243 port 52506:11:  [preauth]
Dec 21 15:05:40 raspi3 sshd[3542]: Disconnected from 221.194.47.243 port 52506 [preauth]

大学の研究用のガチのグローバルIPだと秒間で10とか来てたから、ソレを考えたら少ない方だわ

公開鍵認証のみなので実害はない。

preauth で止まってるし、password をブルートフォース攻撃されるわけでもないので、別にいいんですが、ログをみてるときにちょっと気持ち悪いよね。 家のドアチャイムを定期的にピンポンダッシュされて空き家か調べられるのはっちょっとだけ良い気がしない。

日本国内のIPアドレスに限定してみよう。

ssh のポートについては日本国内のIPアドレスに限定してみようと思い立った。

日本国内のIPアドレスは何処で取れるのか?

ぐぐったらいくつか在るんだけど、今回は、 https://ipv4.fetus.jp/ を使うことにした。

日本国内のIPアドレスは→ https://ipv4.fetus.jp/jp.txt

iptableにコレ全部登録するの?

流石に約3000件を登録するのはちょっと現実的じゃないよね。

iptables で第三国のIPアドレスを制限して、日本国内に限定したいとか思ったんですが。IPアドレスの範囲を指定するのって思った以上に不便。

iptablesの件数がどこまでも伸びていってしまうよね。

ipsetを使います。

ipsetを使えばかんたんに設定できるようです。

調べてみたら カーネルにnetfilter に ipset という、IPアドレスをグルーピングしてフィルタを記述できるセットが用意されていた。

ipset のインストール

sudo apt search ipset 
ipset/stable 6.30-2 armhf
  administration tool for kernel IP sets
sudo apt install ipset

ipset の使い方

ipset は、名前を付けてリスト(フォルダ的なもの)にIPアドレスか、ネットワーク・アドレスをガンガン放り込んでグルーピングしていくもの

ipset でリストを作る・潰す

リストの作り方と削除

sudo ipset create my_list hash:ip
sudo ipset destory my_list

hash:ip は ip アドレスで、hash:net はネットワークで、それぞれ指定する。件数が多いものはまよわず net を使う。

sudo ipset create my_list hash:net
sudo ipset destory my_list

ipset のリストにIPを登録する・確認する・削除する

ip set のリストにIP・ネットワークを登録し確認し、削除する。

sudo ipset add my_list 1.0.16.0/20
sudo ipset list my_list
sudo ipset del my_list 1.0.23.58

ただし、hash:ip で定義したリストに、サブネット切ったネットワークで、ガッツリIPを放り込むと大量にエントリが発生するので注意が必要

hash:net の方がいいと思う。

実際に入れてみた例

$ sudo ipset create my_list hash:net
$ sudo ipset add my_list 1.0.16.0/20
$ sudo ipset list  my_list
Name: my_list
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 396
References: 0
Members:
1.0.16.0/20

国内限定にするフィルタを作る

ipset の使い方がわかったところで、iptables と連携するための ipset を作ります。

日本国内のIPをざっくり取得する

日本に割当てられたIPv4アドレスを取得する

curl https://ipv4.fetus.jp/jp.txt | \grep -v  '^#'

何度も取得に行くと負荷かけちゃうので、適当にキャッシュした方がいいです。

日本国内IPをざっくり登録する

取得した結果のすべてを ipset で自分の許可リストに放り込んで行きます。

$ curl https://ipv4.fetus.jp/jp.txt | \grep -v  '^#'  |xargs -I@ -P 0  sudo ipset add my_list @

登録したら、確認する

登録ができたら確認してみます。

$ sudo ipset list my_list

登録結果を保存する

登録した結果を保存して

 sudo ipset save my_list > my_list.txt

iptablesでフィルタを作る準備をします。

万が一失敗しても死なないように、別ポートでもsshd を起動しておきます。

/etc/ssh/sshd_config

Port 22
Port 2222

port 2222 でもssh を起動しておきます。

ssh -p 2222 で接続ができることを確認

失敗した時でも安心できるように別ポートが使えることを確認

ssh localhost -p 2222

ローカルIPの追加。

今回は、国内限定にする=ホワイトリスト方式。なので、許可リストにローカルIPを入れておきます。

sudo ipset add my_list 192.168.0.0/16
sudo ipset add my_list 10.0.0.0/8
sudo ipset add my_list 172.16.0.0/12

最後に、ipset の登録値を使ってiptablesを構成する

sudo iptables -I INPUT -m state --state NEW -p tcp --dport 22 -m set --match-set my_list src -j ACCEPT

iptables の設定が出来たことを確認

takuya@raspi3:~$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh match-set my_list src

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

設定を保存( permanently/persist)して再起動後も有効な設定 にする

systemd をつかって ipset の取得を定期実行にしたりしておく。

起動時にipset を再度有効にするようにしておく

sudo sh -c 'ipset save > /etc/ipset.conf'

iptablesの設定の保存。これは定番 iptables が再起動後に ipset のリストを使うようにしておく

sudo sh -c 'iptables-save > /etc/iptables.up.rules'

再起動後に実行されるようにする。

再起動に有効にする。

sudo vim /etc/network/if-pre-up.d/iptables-with-ipset
sudo chmod ug+x /etc/network/if-pre-up.d/iptables-with-ipset

/etc/network/if-pre-up.d/iptables

#!/bin/sh
##
## 2017/12/23 記述 
## /etc/network/if-pre-up.d/iptables-with-ipset
## 

# ipset からリストを読み込む
ipset restore < /etc/ipset.conf
# ipset を使ってiptablesを構成する
iptables-restore  < /etc/iptables.up.rules

これで、再起動に有効になる。

メモなど

本当は iptables じゃなくて、openssh側の設定でやりたいんだけどなぁ。

openssh-server の拒否リスト(もしくは MatchAddress )的なところで、ホワイトリストを使えれば良いんだけどなぁ。

iptablesはいろいろな設定をドンドン書いていくので、ゴチャゴチャしすぎて整理できないから辛い。

もしかしてv4の方が使いやすい??

v4 の在庫は枯渇してて、どの国にドレだけ割当てられてるかすでに決まっていて今後大幅に増減はないと考えるなら、v4のフィルタって更新やメンテをあまりしなくても動くんじゃないですかね。

参考資料

https://inaba-serverdesign.jp/blog/20150209/ipset_iptables_country_centos6.html

学習しないフォームを強引に学習させる

パスワード保存は素晴らしい

パスワードのブラウザ保存は素晴らしい。パスワードを「頭に記憶」するなど時代遅れの産物だ。

パスワードはブラウザに保存し、ブラウザやPCにマスターパスワード(もしくは指紋認証)を付けるのがいまどきだとおもう。いまどきキーチェーン機能がないOSなんてあるんですかね。

パスワードを学習させてくれないフォームを学習する

form を横取りしたり、Actionしないフォームを作られると面倒なので学習させる

var p = document.querySelector('input[type=password]')
var f = p.form
f2 = f.cloneNode(true)
f.parentElement.replaceChild(f2, f )
f2.action= location.origin
f2.onsubmit = function(e){ e.preventDefault();e.stopPropagation(); }
f2.submit()

方針としては、とりあえずEventHandlerを全消しして、Actionをフォームと違うURLに送る。そこへSubmit()する。

これで、フォームの入力を学習することが出来る。

もし、form 要素がないときは insert してform 要素を強引に作成すればいい。(icloudなど)

りそな銀行マジ困る。

今回はりそな銀行だった。

ログインの学習くらい平気

ログインした後に、資金移動で第二パスワードを求められるので、そっちを守れば良いわけでログインパスワードを死守しようとする姿勢がまるで理解できなかった。

愚痴など

パスワードは完全な乱数にして、20文字くらい使っていて、なおかつログインIDを「非公開」で憶測不可能なものにするべきだよね。それくらいをやってからセキュリティチェックだの、不審なメールに注意しろとか。そういう出来る限りの対策を行った上で、注意喚起を行ってほしいなどと思う。

ウイルスに注意しろとかいうくせに、DOMDocumentのイベントを横取りしてコピペできなくなってたり右クリックを妨害したり、ミレニアム世代のインターネットのブラクラまがいのウイルス的な行為をやってなぜセキュリティといえるのだろうか。

究極的には、Slackのようにメールクリックしたらログインできるくらいでいい。

イ◯ン銀行とか三菱京U◯J銀行とかCloudFlareとか、ログインした後にメールの番号を要求するからな。。。面倒だしとっととバイバイしたわ。

トークンつかっても防ぎようがないものは防ぎようがない。警察庁金融庁あたりがトークンを義務化するようにガイドラインをだしてるけど、問題はそこじゃないだろって感じはある。

cssの important は上書き出来るんじゃん

CSSセレクタ順位を使えば上書きできる

/*くっそやりやがった・・・*/
#header_navi{
     positon: fixed !important;
}

でも大丈夫かんたんに上書きできる

body div#wrapper div#header_navi{
     positon: inherit !important;
}

とかやれば、単純に上書きできる。

CSSのカスケード順位の方が優先なのでした。

CSSのカスケード順位が同じときに !important で上書き拒否できるんですね。

つまり、

#header_navi{
     positon: fixed !important;
}
div#header_navi{
     positon: inherit !important;
}

これだと div を付けてる分だけ、CSSの順位で、後から提示なのでちゃんと上書きできるんですね。

これで、アドブロックの自作拡張が捗る

参考資料

http://beniyama.hatenablog.jp/entry/2014/08/21/005522

printf のフォーマットを使って覚える。

printf のフォーマットの例

printf で文字の整列などをすれば楽ちんだろうとは思うんだけど、なかなか覚えきれないので、いくつか例を以て覚えておきたい。

takuya@Desktop$ ruby /Users/takuya/printf_examples.sh
prinft %d      32 => '32   '  # 数字
prinft %5d     32 => '   32'  # 右寄せ
prinft %-5d    32 => '32   '  # 左寄せ
prinft %04d    32 => '0032 '  # 0埋め
prinft %-05d   32 => '32   '  # 0埋め+左寄せ
prinft %+d     32 => '+32  '  # 符号(+)
prinft %+d    -32 => '-32  '  # 符号(-)
prinft %.1f   -32 => '-32.0'  # 小数桁1
prinft %.2f    32 => '32.00'  # 小数桁2
prinft %#x     32 => '0x20 '  # 16進数
prinft %#o     32 => '040  '  #  8進数
prinft %#b     32 => '0b100000'  #  2進数
prinft %#08b    7 => '0b000111'  #  2進数0埋め

使ったソースコード

#!/usr/bin/env ruby

formats = {
  '数字'    => [ "%d", 32 ],
  '右寄せ'  => [ "%5d", 32 ],
  '左寄せ'  => [ "%-5d", 32 ],
  '0埋め'   => [ "%04d", 32 ],
  '0埋め+左寄せ'   => [ "%-05d", 32 ],
  '符号(+)' => [ "%+d", 32 ],
  '符号(-)' => [ "%+d", -32 ],
  '小数桁1'  => [ "%.1f", -32 ],
  '小数桁2'  => [ "%.2f",  32 ],
  '16進数'  => [ "%#x",  32 ],
  ' 8進数'  => [ "%#o",  32 ],
  ' 2進数'  => [ "%#b",  32 ],
  ' 2進数0埋め'  => [ "%#08b",  7 ],
  # '金額'  => [ "%'d",  32 ], not supported

}


for k, e in formats do 

  f = e[0]
  v = e[1]

  printf( "prinft %-5s %4s => '%-5s'  # %-5s \n" , f, v , f%v, k   )

end

関連資料

prinft %s は文字列の長さが指定できる! - それマグで!

ubuntu がネットワーク待ち(systemd-networkd.wait)で起動が遅い・・・

ネットワーク周りをいじると再起動が遅いですね。

起動時にネットワーク待ちになる。DHCP待ちになる??

A start job is running for wait for network to be configured.

これで、しばらく時間がかかるので、Virtualboxなどから使ってると大変。

LANケーブル未接続の状態で、起動したときに、起動が遅くて遅くて起動に時間がかかるので、高速化したい。

対策

ネットワークを待たない。

systemctl disable systemd-networkd-wait-online.service
systemctl mask systemd-networkd-wait-online.service

systemd-networkd は、systemd でネットワーク周りの設定を司るやつ。

systemd-networkd-wait-online はsystemd-networkdを待つためのジョブ。個人的には、正直無くていい。

UbuntuのネットワークまわりはSystemdになってからむしろ起動が遅くなって、Systemdで起動速くなる的なのなんだよってなる。

関連資料

ubuntu のネットワーク設定が変わってる /etc/network/interfaces no longer used - それマグで!

参考資料

https://askubuntu.com/questions/972215/a-start-job-is-running-for-wait-for-network-to-be-configured-ubuntu-server-17-1

りそな銀行のパスワードが12文字以下で、こいつらハッシュ化しないんじゃね?と疑問に思う

りそな銀行に口座を作った

近所のファミリーマートが潰れた。サンクスがファミマ転換で近所にファミマが4軒になり、旧サンクスが生き残り、ファミマが閉店した。ファミマのe-net が使えなくなった。半径2Kmが旧サンクスだけになった。ATM難民になった。

近所のサンクスにはBankTimeである。BankTimeはファミマ転換でe-Netになるとかとおもったら、BankTimeのATMのまま継続された。手数料無料での現金の確保が難しくなった。

仕方なくBankTimeを使うためにりそな銀行の口座を作った

BANKTIMEはダメだった。

りそな銀行の口座でも、BANKTIMEで18時以降、時間外手数料を取られる。悔しい。

これじゃ口座を開設した意味ないじゃん。平日の昼間に駅前のりそな銀行に行って、「当支店では口座を開設は住所か勤務地の付近以外の方はお断りしてます」とかいう謎の拒否にも負けず、アレコレ理屈並べて開設したのに。

りそな銀行株主優待で時間外手数料を無料にしてからが本番かな。まぁこれなら新生銀行でいいかと思ったり。

旧サンクスのファミマは当分のあいだBANKTIMEをそのまま運用するらしい(あと数年はこのまま)

りそな銀行のログインパスワードは6−12文字

りそな銀行のログインパスワードは6−12文字。最大文字数が極端に少ないので、このログインパスワードは暗号文にして保存されてシステム管理者が読める状態にあると憶測される。通常であればハッシュ化されるため最大文字数にあまりうるさくないはずだし20文字以上でも問題ないはずだ。

f:id:takuya_1st:20171224031652j:plain

しかも記号が使えない。大文字小文字数字(26+26+10=62種)である。文字数が少ないのであれば、記号は必要だろって感じある。

フリーメールアドレスはお控えください。

理解できなかった。銀行のエンジニアは20世紀で時間が止まってるのか?

スマートフォンのアドレスは「フリーなiCloudGmail」というフリーメールなのではないのか。。。むしろ今時ISPのメアドを使ってて、フリーメールという用語を理解する人がドレだけ居ると思うんだろうか。

f:id:takuya_1st:20171224032140j:plain

秘密の質問とかいう謎セキュリティ

秘密の質問とかいう謎セキュリティがあった。まぁ理解は出来るが、正答登録に憶測されにくいものと指定する割に、サンプルで書いてる質問が出身小学校は?という憶測されるものであり、ツッコミどころが満載だった。

f:id:takuya_1st:20171224032353j:plain

小学校名など、たかだか20未満の候補に限られてしまうので、パスワードに利用してはダメな典型じゃないのか?

ログインシールとかいう謎セキュリティ

これ、何の意味があるんですかね。。MITMされると意味がないし、画像のURLがどの画像を使っても同じだったらセッションハイジャックでも意味が無いと思うんですけど。画像のURLがどの画像を選んでも同じじゃ意味ないじゃん?ゆうちょ銀行の昔のWEBがこんな感じだったな。

URL同じだと無意味だよね・・・

<img id="ctl00_cphBizConf_imgFavImg" 
src="../4001/CreatImagePage.aspx?id=0"
 alt="お気に入り画像" style="border-width:0px;">

f:id:takuya_1st:20171224032540j:plain

てか、こんな無駄な努力するなら、インターネット利用の条件にSSLやEV-SSLの確認方法を紹介して理解しない限り先に進めない仕様にすれば良いんじゃないかな。

そもそも、このログインシールをいつどこでどうやって確認したら安全なのか、ユーザーに説明しないでセキュリティになるんだろうか。と疑念を感じたりした。

何考えたらこういうセキュリティになるんだろうか

メールアドレスの変更に確認メールを送信しない仕様ってのが一番理解できなかったな!

セキュリティとはソフトウェアだけで確保するものじゃない。

ユーザーへの教育や啓発が同時に必要ですよね。ソフトウェア云々じゃないよね。SSLついて教えたほうが速いよね。

そのたUIなどの雑感

画面はシンプルで分かりやすかったから良い。

Chrome のコンソロールの結果をファイルに保存する

console.log の結果を取り出したい。

Chromeデベロッパーツールのコンソールのログに書き出した結果を別の場所で使いたいなと。 いちいち、選択肢してコピーするのも面倒だし、件数が増えてくるとかなり面倒。

また、実行結果をテストケースの結果としてほしいなと思ったりする。

console.log の結果をファイルに取り出して再利用したいなと思った

ブラウザのDOMないに書き出しても良いんだけどソレも面倒だし。もっと手軽にファイルに書き出せないかと。

chromeのコンソールが直接ファイルとつながってくれたら良いんだけど、それも難しそう。

セキュリティ上の懸念もあるし、ブラウザのドキュメントのコンテクスト内で動作しているJSがローカルファイルに直接書き込むことは無理だろうから

どうしようかなと考えてたけど、セカンドベストな方法で妥協することにした。

Save As を使う。

f:id:takuya_1st:20171221190442p:plain

Save As の保存ダイアログ

保存ダイアログを使えば保存は簡単にできる。これがセカンドベストかも知れない。

jot コマンドが便利。乱数・連番生成で、ループ処理や文字列生成にとてもいい。

jot コマンドを知りました。

jot コマンドは、連番の数字やアルファベットを生成したり、ランダムな数字を生成したりに使えます。

連番ファイル名などを作るのに大活躍です。

上手に使えば、Bashスクリプトseq$RAMDOM よりも便利かもしれないっす。

連番を作る

takuya@~$ jot  10 
1
2
3
4
5
6
7
8
9
10

連番をカウントダウン(逆順・降順)

文字列+連番名を作る例

takuya@~$ jot -w  abc 10
abc1
abc2
abc3
abc4
abc5
abc6
abc7
abc8
abc9
abc10

printf のフォーマットで文字列を揃える

takuya@~$ jot   -w 'name%03d'  3 8
name008
name009
name010

アルファベットを連続して生成する

takuya@~$ jot  -w %c 5 a
a
b
c
d
e

アルファベットを連続して生成して、区切り文字で連結する

takuya@~$ jot -w %c -s '_'  5 a
a_b_c_d_e

乱数を作る

takuya@~$ jot -r 3
40
73
84

指定範囲の乱数を作る

takuya@~$ jot -r 1  1 10
7

指定範囲の乱数を指定回数生成する

1から10までの乱数を3つ生成する

takuya@~$ jot  -r 3  1 10
8
10
5

乱数+文字列を作る

takuya@~$ jot -w abc -r 3  1 10
abc1
abc10
abc9

結果を文字列として結合する

乱数+文字列を連続してプリントする。

takuya@~$ jot -s aa  -r 3 10 100
25aa78aa70

応用して、ランダムなビット列っぽいものを作る

takuya@~$ jot -s ''  -r 10 0 1
0110110100

ランダム文字列を作る

ランダムな文字を生成して、結合してしまえばランダムな文字列が得られる

takuya@~$ jot -r -s '' -c  10   a z
oiaisaqaft

参考資料

シェルスクリプトで乱数を扱う - hyconの日記