Pwnableの本をRe:VIEWで作って技術書典7で頒布した

Malleus CTF Pwn

sanya.sweetduet.info

techbookfest.org

自分のためにも色々とメモを残しておこう思っていたけど、1か月以上経ってしまった。 とらのあなにはまだ物理本の在庫が残っているし、電子版はBOOK☆WALKERにあるのでよろしくお願いします。

Pwnableというテーマについて

CTFに参加したことのない人には「なんだそりゃ?」だと思う。 CTFのジャンルの一つ。 C言語C++で書かれたプログラムが問題として与えられて、そのプログラムは出題者のサーバーでも動いている。 プログラムを解析してバッファオーバーフローなどの脆弱性を探し、その脆弱性を攻撃するスクリプトを書いて、出題者のサーバーからフラグの書かれたテキストファイルを奪取するというのが典型的な流れ。 セキュリティのコンテストと聞いてまず想像する形式だと思う。 花形ジャンルなのでたいていは問題数が多いし、解けるとカッコイイ。

しかし、私はpwnableが苦手。 1問も解けなかったり、解けてもチュートリアル的な簡単な問題だけということが多い。

Pwnableは他のジャンルに比べて狭くて深い。 例えば、webの問題で ' を入力したときにエラーになったらその場でSQL Injectionについて調べて解けるかもしれないけれど、pwnableで長い文字列を入力して落ちたからといってそこから何も知らない人が解ききるのはまず無理だと思う。 よっぽど簡単な問題でもない限り、スタックやライブラリのアドレスはランダム化されているし、書き込み可能な領域は実行不可能なので、ROPでlibcのアドレスをリークしてOne-gadget RCEか何かでシェルを取る必要がある。 最近だと system 関数を呼び出すときにスタックが16バイト境界に揃っていないといけないという問題にハマる。 そもそも、問題文にファイルへのリンクとサーバーのアドレス・ポートしか書かれていないことが多いので、このファイルがサーバーで動いているということも分からなそう。 一方、他のジャンルに比べて必要とされる知識は多くない。 一度覚えたテクニックは使い回せるし、何か新しい脆弱性があってそれを知らないと解けないということもない。

ということで、一回ちゃんと勉強すればその後のコンテストで得点源にできるし、ついでにそれを本にしようと考えた。 「お前の勉強ノートを売りつけるのか?」と言われそうだけど、この後のpicoCTFではpwnableの問題は全部解けたし、SECCONの予選で2桁チームしか解いていない問題を解ける程度の実力は付いた。

表紙

サークルカットには頒布する表紙を使い回すのが定番。 申込時に必要なのでまずは表紙用の画像を作らないといけない。 とはいえ、サークルカット無しで受かっているサークルもあるし、抽選にもサークル配置にも使われないなら、実はサークルリストが一般公開されるタイミングに間に合えば良いのか?

と、写真イラストは過去に実績を解除したので、次はCGにしたかった。 ジェネラティブアートに挑戦したかったけれど、難しそうで断念。 写真を元にプログラムで生成した。 遠目で見ると画質が悪いようにしか見えないけれど、近くで見ると良い感じで気に入っている。

紫陽花の写真を撮ります。

f:id:kusano_k:20191115044424j:plain:w400

最近のフォトショップなら人工知能が何とかしてくれるらしいけど、そんなものは無いので、手作業で切り抜きます。

f:id:kusano_k:20191115044709p:plain:w400

ボカしたり色調を調整したりして良い感じにした別の写真を用意します(A)。

f:id:kusano_k:20191115044832j:plain:w400

重ねます(B)。

f:id:kusano_k:20191115044950j:plain:w400

Aに文字を置いていって、Bに近づけます。 ただし、良い感じにランダムさがほしい(背景にもちょっとは文字を置いてほしい)ので、こんな感じのプログラム。

image = A
for c in 文字列:
  font_size = 徐々に小さくする
  # 各サイズで合計面積が同じになるように、小さい文字ほど個数を多くする
  for i in range(64):
    color = ランダム
    x = ランダム
    y = ランダム
    (x, y)に色colorで文字cを試しに置いたときのBとの差分を計算
  最も差分が小さくなるcolor, x, yでimageに実際に文字を置く

実際には、文字の座標や色を出力しておいて、影を付けたりちょっと透明にしたりして生成し直した。

f:id:kusano_k:20191115045859j:plain:w400

ノイズを加えたり、グラデーションを掛けたり、タイトルを書いたりします。

f:id:kusano_k:20191115050118j:plain:w400

原寸大だとこんな感じ。

f:id:kusano_k:20191115050321p:plain

ちなみに、描いている文字はglibcmalloc.cからコメントを取り除き、(文字が多すぎたので)1/8の確率でサンプリングしたもの。 プログラムコードのような雰囲気が出るかもしれない。 各文字の頻度情報しか残っていないはずなので、GPL適用は勘弁してほしい。

問題

単に説明を書いていくよりも、具体的な問題を解いていったほうが面白いし書きやすい。 ということで問題を作ることにした。

github.com

前半の問題はスタック、後半の問題はヒープ、間に書式文字列攻撃を挟んだ。

Pwnableの問題ではサーバーが必須。 しかし、サーバーの管理は面倒だし、後から本を買った人も遊べるようにしようと思うと、いつまでもサーバーを動かし続けないといけない。 Dockerで各自の手元で動かしてもらうことにした。 Dockerの中身を覗けばフラグが得られてしまうけれど、これで何かを競おうというわけでもないので、まあ良いだろう。 この問題と後述のRe:VIEWのビルドで、Dockerを初めてしっかり使ってみたけれど、とても便利。 流行るわけだ。

スコアサーバー(?)はNuxt.jsで静的ファイルを生成。 適当にハッシュ値でも取ってフラグをチェックすれば、クライアント側で処理しても、解析されてフラグが漏れることはない。 サーバーは要らない。

github.com

事前に問題を公開することで、解いた人がツイートとかしてくれて、宣伝になるのではという目論見があった……が、解いてくれる人があまりいなくて目論見は外れ。 Docker Hubのpull数は10くらいだった。 下心が見透かされたか、Dockerとはいえ手元で動かすのは面倒だからサーバーを立てておくべきだったか、そもそもpwnableはハードルが高いのか……。

今までの本は、Markdownで書いてPandocでPDFに変換していた。 今回はRe:VIEWを使うことにした。 技術書典だとRe:VIEWを使っている人が一番多いと思う。 長いものには巻かれろ。

Re:VIEW、荒削りだけれど、独自記法からPDFやepubの変換に特化している分、Pandocに比べて楽。

PandocだとMarkdownを書くだけでは解決できないことがあって、どうしてもLaTeXを書く必要が出てくる。 Re:VIEWならRe:VIEWだけで完結しないかなと期待していたけれど、そんなことはなかった。 LaTeXでちょこちょこ調節する必要があるし、何かにハマったときにRe:VIEWソースコードも読んだ。

Re:VIEWを一から書いたり、環境を構築するのは大変なので、TechBoosterのテンプレートとDockerを使った。

他の選択肢として、Re:VIEW Starterがある。 Re:VIEWに対する不満が解消されていて良さそうではあるけれど、Re:VIEW 3に対応していないのが残念。

技術系同人誌を書く人の味方「Re:VIEW Starter」の紹介 - Qiita

余談だが、この辺とかこの辺とかがだいぶ殺伐としていて良い。 競い合って良い感じになってほしい。

Re:VIEW Templateに書かれているコマンドでDockerでビルドすると、毎回npm installが走って遅いし、npmにも迷惑が掛かりそうなので、

docker run -it -v %CD%:/book --name review vvakame/review:3.2
cd /book
./setup.sh

を最初に実行して、ビルドするときには

docker start review
docker exec review /bin/bash -ci "cd /book && REVIEW_CONFIG_FILE=config.yml npm run pdf"
docker stop review

としていた。 Windowsでカレントディレクトリは%CD%。 Dockerはなぜディレクトリのマッピング相対パスで指定できないのか。

生成したPDFから一部の漢字をコピペすると部首になる問題と、GCCの出力の

fsa_test1.c: In function ‘main’:

このクォーテーションマークのせいで埋め込まれないフォントが使われる問題にハマった。 対応されているので、最新のDockerイメージを使えば大丈夫。 ありがたい。

電子版

今までは紙の本だけだったけれど、PDF版も作ることにした。

Re:VIEW Templateならば、config-ebook.ymlを使えば、トンボが無かったりリンクがクリックできたりするPDFが作れる。 後はPDFの編集ができる有料版のAcrobatで表紙と裏表紙を貼り合わせる。

f:id:kusano_k:20191117044522p:plain

そのままだと開いたときに本文の1ページ目にスクロールしてしまうので、表紙(PDFとしての1ページ目)を「開くページ」に設定。 ついでに、デフォルトのページレイアウトを見開きにした。

PDF版の配布方法。 ダウンロードカードごとにちゃんとパスワードを変えている人もいるけれど、まあ共通パスワードで良いだろう。 パスワードを変えるとダウンロードカードの用意が大変。 PHPか何かでサーバー側のスクリプトを書くなり、HTTPサーバーの設定なりでパスワードを入力してPDFをダウンロードするようにするのは簡単だけど、この先サーバーを移したりすることを考えると、静的ファイルにしておきたい。 PDFは暗号化したZIPに入れて、JavaScriptで復号するようにした。

Malleus CTF Pwn 電子版ダウンロード

問題はスマホで、パスワードを入力してPDFを表示することはできても、保存することができない。 blob://のURLをブラウザから他のアプリに飛ばしても、他のアプリから読めない。 ダウンロードカードにはたいていQRコードが付いていることを考えると、スマホでダウンロードする人も多いのだろうか。 まあ、技術書典に来てこの本を買う人でPCを持っていない人はいないだろう……。

ダウンロードカード。 名刺サイズを良く見るけれど、私がダウンロードカードを買ったときに無くしそうで怖かったので、ポストカードサイズにした。 kinko'sで200枚印刷して1万円掛からないくらい。 郵便番号欄とかが無いものでもいけるのかちょっと心配だったけれど、特に問題は無かった。 本と違ってポストカードなら大量に余っても場所を取らないので、200枚刷ったけど、電子版を買う人はあまりいなかったので、200枚も要らなかったな。 電子版を買う人は技術書典かんたん後払いシステムを使っていることが多いので、システムのダウンロード機能だけで充分だったかもしれない。

ポストカード印刷・DMハガキ印刷・プリント | サービス・料金(価格) | オンデマンド印刷のキンコーズ・ジャパン

Illustratorでデータを作って持っていったら「これ、アウトライン化されてないですね……。まあこちらで何とかしておきましたけど」と言われた。 ごめんなさい。

肝心のパスワードを間違えるという重大ミスをやらかした。 Ctrl+vで貼り付けるときに、Ctrlが抜けたっぽい。 ごめんなさい。

電子書籍

せっかく電子版を作るのだから、技術書典後にオンラインでも売りたい。

定番はBOOTHでPDFを販売。 しかしBOOTHは販売者がBOOTHではなく自分なのがちょっと気になる。 電子書籍も作ってみたい。 AmazonKindle Direct Publishingは料率が低い。 ということで、BOOK☆WALKERにした。 同人に力を入れている感じがあるのも良い。

EPUBという形式で作るらしい。 Re:VIEWは対応している。 PDFのようにどのデバイスでも同じように表示するのが目的の形式だと思っていたけれど、そんなことはなくHTMLをZIPで固めたものだった。 ウェブサイトでブラウザごとに見た目を調整するのと同じ対応が必要。 つらい。 コード領域のスタイルを font-family: monospace, serif; にするとか。

silight.hatenablog.jp

何かのチェッカーに掛けたら、「画像ファイルが無いけど大丈夫?」みたいなことを言われたので、この部分を消した。 Re:VIEW Templateはあくまで「TechBoosterで利用しているRe:VIEWのテンプレート」か。

github.com

BOOK☆WALKERのブラウザビューアはコード領域が等幅フォントにならなかったりしてつらい。 頑張ろうにも事前に手元で見た目を確認する手段が無い。 電子版でも別途PDFをダウンロードできるので、そちらを見てほしい。

お釣り

冊子版は1,000円で、電子版はちょっと安く900円にしたので、お釣りが必要。 みずほ銀行をメインで使っているので、両替機で両替。 両替機に来月から10枚が上限になるというお知らせがあった。 使い物にならない。 今回両替した100円玉は大事にとっておこう。

技術書典当日

今回は2フロア開催。 私は3階。 ちゃんと早めに行ったのに、サークル入場に時間が掛かって、開場までギリギリ。 たしかに、2階より人が少ないというのも感じた。

note.mu

「3階であまり売れなかった」と怒っていた人もいたけれど、まあ、今までの技術書典の売れ行きが良すぎたのかもしれない。 買う側の自分としても「あれ? 技術書典で買った本を次の技術書典までに何冊読んだっけ?」と気が付きつつある。 委託販売をしてくれているサークルも多いので、買い逃しても何とかなるし。

ということで売れ残った分をとらのあなの受付に預けて終わり。 ダイレクト入庫サービスが楽で良かった。 事前に申込みしておけば、当日受付に本を持っていくだけ。

AtCoderで青色になるまでにやったこととプログラマー35歳定年説

f:id:kusano_k:20190925052150p:plain
https://atcoder.jp/users/kusano

はい。 みんな「AtCoderで○色になるまでにやったこと」みたいなタイトルで、右肩上がりのレートのグラフとともに楽しそうな記事を書きやがって。 こちとら2年かけてジワジワとレートが下がり、とうとう下の色に変わってしまった。

これがやりたかっただけなので、競技プログラミング力の向上に繋がる有益な話は、この記事にはほとんど無い。 解答を清書してブログに解説記事を書くというのはオススメだけど。

私と競技プログラミング

「○色になるまで」という記事には、いつ頃から競技プログラミングを始めて、○○年頃には何をしていたか、みたいなことを書くものらしい。

Cマガ電脳クラブ

今の競技プログラミングとはちょっと違うけれど、「Cマガ電脳クラブ」が最初だろうか。 今は無きC MAGAZINEという雑誌があり、その中の「Cマガ電脳クラブ」というコーナーで、問題が出題されていた。 解答と解説を送って正解していれば、雑誌に名前が載る。 2人が選ばれて解説も掲載される。

問題はこんな感じ。 だいたいは、探索して何らかの枝刈りを入れれば現実的な時間で解けるというもの。 AtCoderなどで慣れた人なら1時間も掛からずに解けそう。

f:id:kusano_k:20190925051245j:plain
C MAGAZINE 2004年7月号

中身の分からない複数のテストケースに通るプログラムを書くのではなく、問題に書かれている答えが導ければ良い。 2人が選ばれると言っても、提出時間などが競われるわけではなく、担当者の主観で選ばれる。 実行速度が速いとか、解法がユニークだとか。 関数を一切使わずにプリプロセッサマクロだけで解いたという解答もあった。

2002年から廃刊までだいたい毎回送っていて、何度か解説が載ったこともあった。

ACM-ICPC

2008年。 知ったのが修士1年のときだから、一度しか出られなくて残念(年齢制限があって、修士1年くらいまで)。 もっと早くに知っていれば……。 今の大学生は学部1年から出ている人が多くて羨ましい。

TopCoder

で、ACM-ICPCが終わった後も「これは面白いな」と過去問を解いているときに、研究室の助教に「こんなサイトもあるよ」とTopCoderを勧められたのだったかな。

f:id:kusano_k:20190925055941p:plain
https://www.topcoder.com/members/kusano/details/?track=DATA_SCIENCE&subTrack=SRM

当時は定期的にコンテストを開いているサービスはTopCoderしか無かった。 TopCoderは(今はウェブからも参加できるけれど)Javaアプリをダウンロードして動かす。 当時は、リアルタイムにランキングを更新したりするのはそりゃウェブでは無理だよなと思っていた。 ウェブの技術の進歩はすごい。 Ajaxなんて言葉もこの後に流行った。

TopCoderは最初は黄色だったものの青に落ち、しばらく足掻いて、赤にタッチするところまではいった。 そしてその後だんだんレートが下がっていった。

天下一プログラマーコンテスト2009

今はあちこちの会社がコンテストを開いているけれど、10年前はそんなことはなかった。 Googleくらい。 そんな中、KLabが1回だけコンテストを開いたことがあった。

懐かしんで探したけれど、今も残っている様子が分かる記事がこのブログ1個しか見つからなかった。

天下一プログラマーコンテスト決勝 - suztomoのはてなダイアリー

1日目2.5ポイントのsuperflipが私の1人チーム。 この頃にルービックキューブで最短手数が最長となるのはどの状態か?というのが話題になっていた。 その候補がSuperflipという状態で、そこからチーム名を取った。 今でもCTFに出るときに使っている。

[B! イベント] shi3z on Twitter: "天下一カウボーイ大会は登録商標なので、類似商号をつかうつもりなら、裁判するしかないなあ http://www.klab.jp/tenka1programer/bosyu.html"

「『天下一』という名前はうちの商標だ。訴えるぞ」

「お前も天下一武道会のパクりだろうが」

というやりとりを見かけて、「IT業界はサツバツとしているなぁ」と思った覚えがある。

Codeforces

2010年Codefoces開設。

英語が読めない(私の英語力が無いのは認めるけれど、どうもロシア語の問題を英訳していたようで、Codeforcesの英語もひどかった)し、コンテストは不安定だしで、数回参加して終わり。 いつの間にかTopCoderを抜いて、世界トップシェアになっていた。

f:id:kusano_k:20190928170504p:plain
https://codeforces.com/profile/kusano

http://codeforces.com/profile/kusano

AtCoder

2012年AtCoder開設。 このときは今ほど参加者が増えるようになるとは思っていなかった。

プログラマー35歳定年説

年々調子が悪くなっているのは、AtCoderだけではない。 Google Code Jamでは10年くらい毎年Tシャツを獲得していたけれど、2017年はメインのGoogle Code Jamがダメで、Distributed Code Jamで獲得。 今年2019年はDistributed Code Jamは無く、Google Code JamもダメでTシャツが得られず。

年齢もいつの間にか30歳を超えていたし、プログラマー35歳定年説が頭をよぎる。

レート、どうすれば回復するんだろうなぁ。

半年前くらいに、「これはマズい」と思ってAtCoderの過去問を埋め始めたけど、ABCの最初のほうのDに難しいものがあって、そこで詰まって止めてしまった。 レートへの効果は特に無し。 まあ、簡単な問題の数をこなしても意味が無いのだろう。

f:id:kusano_k:20190928171846p:plain
https://kenkoooo.com/atcoder/?user=kusano#/user/kusano

2018年の6月頃にちょっとAtCoderのレートが回復している。 特に何もしていない気がする。 各回のパフォーマンス(各回の成績、AtCoderのレートはこれの重み付け平均)を見てみると、たまたま調子の良かった回があっただけっぽい。

f:id:kusano_k:20190927064947p:plain

そもそも、2016年頃のレートの上昇もレートの付き始めだからであって、パフォーマンスはAtCoderの開設以来ずっと下がっている。 TopCoderのレートを繋げて見ても、2012年がピークで、そこからはジワジワと下がっているんだな。

この頃は、解いた問題を解説とともにブログに書くということをしていた。 コードも提出したものをそのままではなく綺麗に書き直していた。

kusano_progの日記

これはたしかに効果があった。 後から解くと、コンテスト中の焦りが無いので思考が整理できる。 だんだんコンテスト中でも同じように理路整然と考えられるようになる。 しかし、当時のTopCoderは作問者の解説があったり無かったりであっても当然英語なので、ブログを見てくれる人がいてモチベーションが続いたけど、今のAtCoderだとコンテスト直後に公式の解説が上がるんだよな。

2013年は就職した年でもある。 「仕事で毎日プログラムを書いているだろ」と言われそうだけど、書いてない。 職業プログラマーはコードを書かないからね。 1週間に100行書いたら多いほう。 いや、主語がでかいな。 少なくとも私はそう。

別に、マネージメント的な業務があるとか、事務作業が多いとかではない。 大規模なシステムだと、ちょっとした修正でも内容を雑には決められないし、既存のコードの把握にも時間が掛かるし、バグがあったらエラいことなので慎重にならざるをえないし、ドキュメントを書いたり負荷検証をしたりもある。 変なコードを入れると、自分とチームメンバーがこの先10年とか苦しむことになるというプレッシャーもある。 そもそもコードを書いたところで、AtCoderの後半の問題のような高度なアルゴリズムなんて使わないし。 「競技プログラミングは業務の役に立つのか?」が定期的に話題になるけれど、競技プログラミングが役に立つ状況になったら、それは黄色信号だと思っている。 すごい人が難しいアルゴリズムで問題を解決したとして、その後の機能追加とかメンテナンスとかはどうするんだと。

昔のAtCoderの問題を見て、「この問題をこの時間で解けるか?」と考えてみると、解けそうなので、プログラミング力自体は落ちてはいないと思う。 でも、例えばアルゴリズムの良い解説なんかは蓄積されるし、人類全体は進歩するので、現状維持(もしくは+ε)では、相対的に下がるというなのかもしれない。 昔のTopCoderは、動的計画法ができればレッドコーダーになれたし、Binary Indexed Treeなんかは難問に使われる秘技感があったぞ。 結局、力が付いたのは、真面目に取り組んでいた2010年から2012年の間だけと。 この頃は日頃から競技プログラミングの問題を考えていた。 毎週末のAtCoderに参加するだけではダメっぽい。

ちゃんと練習すればレートも回復するのかもしれないが、やる気が出ないな。 この記事を書くのに昔のことを思い出していたけれど、そういえば昔はプログラムを書くだけで楽しかった。 本のコードを写経して動くだけでも楽しかった。 今は面倒なだけ。 プログラミングは手段ではあるが目的にはならない。

B - Sorting a Segment

例えば青に落ちたこの前のAtCoder Grand ContestのB問題だと、正解すればもちろん嬉しい、「ソート済みの連続するK要素と、連続するK+1要素で左端が最小で右端が最大のものを数えれば……」とかアルゴリズムを考えるのもパズル的でまだ楽しい。 ここから境界条件などを考えながらコードに落とす作業が面倒でしかない。

プログラマー35歳定年説というのは、能力の問題ではなくやる気の問題で、やる気が無くなって後進に追いつかれるのがこの辺の年齢ということなのかもしれない。 どうしたものか。

裸族のスカイタワーのファン換装

【販売終了】 裸族のスカイタワー 10Bay SATA6G (CRST1035EU3S6G) - 株式会社センチュリー

これ。 HDDが10台まで入るので、8TBのHDDを挿していけば合計80TBのストレージになる。

やっぱりダメだったのでファンを交換することにした。

f:id:kusano_k:20190620012528j:plain

左が元々付いていたファン。 ARX DC BRUSHLESS FD1214-S1053E。 同じくらいの風量が良いと思うのだけど、ググっても情報が出てこない。

右が交換用に買ったファン。

CFZ-140GLA | Ainex

補足 CFZ-140GLの型番変更品です。違いはありません。なお、中央の丸ラベルは旧型番のままで変更はありません。

どういうこっちゃ……。

裸族のスカイタワーの筐体はタワー型デスクトップと同じ作りで、後ろのネジ2個を外して、側面のパネルを後ろにスライドすれば開く。 固くて他にネジがあるのかと思ったけれど、そんなことはなく、ドライバーでこじれば外れた。

ケーブルの長さが足りないとか、コネクタ形状が合わないとか、そういう問題は無く、素直に交換完了。 風量も手を当てた感じは同じくらい。 HDDの温度が50度を超えるので、どうせならもっと風量の多いファンに交換しても良かったかもしれない。

追記。

55℃になってCrystalDiskInfoの温度が赤くなる。 さすがに怖いので、noctua NF-A14-PWMに交換。 フル回転でもそんなに煩くない。 温度は50℃前後。

PCを買った(2018年版)

PayPayが上限5万円まで20%ポイント還元ということで新しくPCを組んだ。 買ったパーツをメモしておく。 「今使っている電源は何だったっけ?」というときに、いちいちPC本体を確認するのは面倒。

今まで使っていたPCは4年前に買った。 CPUはCore i7-4790、メモリーは16GB、SSDが240GB。 Cドライブが足りないくらいでスペックには特に不満は無いが、USBポートがダメになったり、たまに再起動したりして困っていた。 USBポートがまともに動くなるようになるのは当然として、4年も経っているのだから、普段使うときにも快適になるかなと思ったけれど、体感できるほどに変わることは無かった。 ムーアの法則は終わった。

ハイエンドとまではいかなくてもそこそこ良いものを、多少のスペックよりは安定をという方針。

ケース: Fractal Design Define R6 - Black - Tempered glass

もうそんなにパーツを組み替えることもないので、小さいなケースにしようと思っていたのに、どうしてこうなった。 たしかに組み立てはすごく楽。 置き場所も作業スペースも広ければ、ケースは大きいほうが良いのだが……。 HDDは逆側から入れるので、PCを奥に押し込めている場合は、引っ張り出さないといけない。 電源ボタンやUSB端子が上面に付いていて、光学ドライブを付けなければ前面は全く使わないから、前後を逆にして壁に押しつけられる。 良い。

店に展示してあるPCは側面が透明のものが多いし、マザーボードにもRGB端子が付いているので、どうせ飽きるだろうなとは思いつつも、一度は側面が透明なものを試してみたかった。 案の定、3日で飽きた。 ケースは中身を保護するためにあるのに、もし何かでPCを持ち運ぶことになったら、ガラスに気を使わないといけない。 これしか無かったので内部のパーツが白いものにした。 黒いほうが良いかと思ったけど、CPUファンなどを光らせたときに、白だと色が良く分かる。

電源: CORSAIR RM750x

750W。 PCの調子が悪くなるのはだいたい電源がへたったときだと思っている。 なので、容量大きめで有名どころを。 どうだろうか。

マザーボード: ASUS TUF Z390-PLUS GAMING

ミリタリーグレードのTUFチョークコイルがどうたらこうたら。 高信頼性を謳っている高いものを買ったのだから、今度はUSBポートが壊れたりしないでくれ。 PayPayで当たりが出て、全額キャッシュバック✌

CPU: Intel Core i7-9700K

別にオーバークロックはしないのだが、最新世代のCPUは「K」付き(倍率ロックフリー)しかなかった。 i5-9600Kでも良かったのだけど、IntelのCPUは品薄らしく、店にこれしか無かった。

CPUクーラー: Scythe 虎徹MarkⅡ TUF

オーバークロックはしないので特に拘りはない。 ちなみに、「K」付きのCPUにはクーラーは付いてこないので、何かしら買わないといけない。

無駄に光る。 最近のマザーボードや周辺機器にはRGBの発光を制御できるピンが付いていて、マザーボードから色をコントロールできる。 負荷状況に応じて色を変えるような設定もできるらしい。

ケーブルがメッシュで包まれていて固いので、ズレてファンに当たってしまう。 ガムテープでヒートシンクに貼り付けた。

モリー: crucial W4U2400CM-8G

DDR4 PC4-19200 8GBの2枚組。 定番ブランドということでcurcial。 ヒートシンクの付いたかっこいいメモリーのほうが良かった気もするが、まあいいや。

「16GBは基本的人権」みたいな話を聞くので、前のPCですら16GBだったし32GBか64GBくらいにしようかなと思っていたけれど、値段を見てヒヨった。 一時期は最安値の2倍くらいの価格になっていたらしい。 PCパーツで値上がりとかあるのか。 暗号通貨みたい。 いくで。やるで。DDR4メモリー買い増しや。

グラフィックボード: ASUS TURBO-RTX2070-8G

今回のパーツの中で一番高い。 ゲームはしないが、ディープラーニングで何かやるぞという決意。

SSD: Intel 760p 512GB

小さい。 マザーボードにネジ止めする。 ストレージが1 TB程度で良いなら、SATAケーブルは要らないのか。

HDD: Western Digital WD6003FZBX

ストレージが512 GBではさすがに足りないので。 WDのHDDは色がいくつかあって、パフォーマンスの黒。6 TB。 HDDが増えても面倒だから、「8 TB未満のHDDは買わないぞ」という信念があったが、黒は8 TBモデルが無かった。

OS: Windows 10 Pro

前のPCのOSはDSP版のWindows 7をアップグレードしたもの。 OSと一緒に買ったパーツさえ移せば、「前のPCのパーツを交換しただけだ」と強弁できそうな気もするが……まあ、買っておこう。

HomeとProの違いのうち気にしていたのは、リモートデスクトップと、グループポリシーを使って正攻法でWindowsアップデートの再起動を止められること。 どちらも、代替手段はありそうだけど、まあ、Proにしておこう。

値段

種別 パーツ スペック 価格
ケース Fractal Design Define R6 23,630
電源 CORSAIR RM750x 750 W 15,789
マザーボード ASUS TUF Z390-PLUS GAMING 17,992
CPU Intel Core i7-9700K 8 コア, 3.6 GHz 51,494
CPUクーラー Scythe 虎徹MarkⅡ TUF 5,470
モリー crucial W4U2400CM-8G 16 GB 21,578
グラフィックボード ASUS TURBO-RTX2070-8G 8 GB 83,700
SSD Intel 760p 512GB 512 GB 26,978
HDD Western Digital WD6003FZBX 6 TB 28,870
OS Windows 10 Pro 27,410
302,911

ポイントは、普通10%還元のところ、PayPay払いだと8%還元。 ものによってはポイント無し。

改めて計算してみると、ボーナス後と、PayPay100億円の熱気に当てられたのとで、調子に乗った感がある。 しばらくは倹約に努めよう……。

技術書典4

初めて技術書典にサークル出展した。

https://techbookfest.org/event/tbf04/circle/19360001

技術書典は通運会館で開催された第1回に一般参加したことがある。 そのときもとても混み合っていた覚えがあるけれど、そもそも会場が狭かった。 今回のアキバ・スクエアは広いのに、それでも混んでいた。 参加者は6,000人越えらしい。

頒布物

とりあえず、C92とC93で頒布した本を持っていくことにした。

日光企画とねこのしっぽなら直接搬入ができるらしいが、印刷会社を変えるのは勝手が分からず何かミスりそうで怖いので止めておいた。折りたたみ式のキャリーカートなら使っても良いらしく、買ってはみたけれど、キャリーカートでも大変そうなのでやっぱり宅配便で送った。正解だったと思う。印刷会社から直接宅配便で送ってもらえば、送料が1回分節約できたのだろうか?

新刊が無いのは寂しいので、次のコミケで頒布しようとビットコイントランザクションスクリプトを調べていたことを書いてコピー本を作ることにした。

ビットコインブロックチェーンに溶けていく様子。

コンビニの印刷機でもKinko'sでもだいたい白黒1面10円くらいで、冊子印刷だと1面に2ページ入るので、1ページ5円くらいになる。セブンイレブンはファイルを事前にネットで登録しておいて印刷できるものの、これだと値段が倍になる。USBメモリに入れて持って行ったほうが良い。セブンイレブンは印刷の品質が良いが折りもステープラー綴じもしてくれない。Kinko'sはステープラー綴じまでしてくれるものの、冊子印刷の場合はUSBメモリのファイルから直接印刷はできず、一度普通に印刷してスキャンする必要があって品質が落ちる。悩ましい。「Kinko'sでPCをレンタルして出力すれば何とかなるかも」という話を聞いたので次があれば試したい。

売れ行き

「ZIP、完全に理解した」は早々に完売。「ksnctf C92」は、あまり売れないだろうと思って、ZIPの半分刷った。こちらもしばらくして完売。「モナーでもわかるビットコイントランザクションスクリプト(プレビュー版)」はあまり売れず。既刊よりこちらのほうが売れるかなと思い、ネットプリントにアップロードして、完売しても欲しい人は番号で印刷できるようにと考えていたが無用な心配だった……。みんな「完売した」と言っているし、あれだけ参加者がいれば何でも売れそうなものだが、そんなに甘くはなかった。

f:id:kusano_k:20180504234304p:plain

Twitterでプリント番号を共有するというのを見かけた。 いつの間にか、ネットプリントがそれに対応してシェア機能が付いていた。

今後

「ZIP、完全に理解した」は、COMIC ZINに「再販してくれ~」と頼んだらOKをもらったので、印刷を発注した。 来週くらいには在庫が復活すると思う。

COMIC ZIN 通信販売/商品詳細 ZIP、完全に理解した

「ksnctf C92」は、ちまちま印刷するのも面倒なので電子化しようと思う。

Chinachuで録画サーバーを作った

https://chinachu.moe/

今まではメインで使っているデスクトップPCでアニメを録画していた。 特に土日の夜にアニメが集中していてPCを再起動することができずに不便。 録画専用のサーバーを作ることにした。

DockerやAnsibleでのコード化はしていてないので、自分のためにも過程をメモしておく。

ハードウェア

今ではプレミア価格になっているPT3が2枚付き。 ベースはProLiant MicroServer。 音はとても静か。 CPUが非力なので、ブラウザの視聴はカクカクで使い物にならなかった。

ICカードリーダーは、SCR3310-NTTCom。 確定申告の電子申請にも使える。

録画用に4 TBのHDDを増設した。 「Linux HDD増設」とかでググって使えるように。

概要

そもそも、ChinachuとMirakurunの関係が分かっていなかった。 ChinachuはMirakurunに放送の録画を投げる。 Mirakurunは複数のソフトから依頼を受け付けて、録画デバイスを上手いこと使い分ける。 EPG番組表の取得もMirakurunの仕事。 Mirakurunはさらに録画コマンドに処理を投げる。 下のレイヤーから作業を進めると動作確認ができて良い。

OS

ネットの記事を見るとUbuntuの例が多い。 Ubuntuを適当にインストールしてSSHで繋げられるようにする。

ドライバ

カードリーダーは標準ドライバで動く。 aptで何をインストールしたか忘れたけど、pcsc_scanJapanese Chijou Digital B-CAS Card (pay TV)と出てくれば良い。

PT3も標準ドライバで動く。 /dev/dvb/adapter?がPT3の枚数×4個見えれば良い。 偶数が衛星波、奇数が地上波。 使うドライバによって、使う録画コマンドが異なる。 標準ドライバのほうが安心だと思ったけど、PT3専用のドライバのほうが使っている人が多くて楽だったかもしれない。

録画コマンド

recdvb(PX-BCUD対応版)のインストール « » Sat's space

recdvbをインストール。 この記事に載っているコマンドで視聴可能な.tsファイルが生成されれば良い。 ただ、このままだとちょっと問題がある。

recdvbrecdvbchksigSNRが取得できない。

USB接続で地デジ4チャンネル録画できるチューナーPX-Q1UDを買ったそして試した - Write and Run

この記事のパッチを当てる。

BSプレミアムなどの番組情報が取得できない(録画もできない?)。PT3にTSIDを渡さないといけないチャンネルがあるらしい。TSIDが何で、どこのレイヤーで効いているのか、分からん。

PT3 + recdvb + MirakurunでNHK BSプレミアムのEGPが取得できない問題に対応 - I am a wannabe.

PT3環境でmirakurun と http://www13.plala.or.jp/sat/recdvb/recdvb-1.3.1.tgz の組み合わせでEPGが取得できない問題に対する修正

このパッチを当てて、さらにコメント欄の修正を加える。 この辺りは4月以降のBSチャンネル再編で修正が必要になりそう。

Mirakurun

https://github.com/Chinachu/Mirakurun

npmに登録されている。 が、一部のチャンネルで録画したファイルがTVTestで視聴できなかった。

PATの書き換えでTSパケットの空きを0xffで埋めるようにした by kusano · Pull Request #34 · Chinachu/Mirakurun

この修正を加えたら、TVTestでも見られるようになった。 手元でビルドしてインストール。 手順は、

https://github.com/Chinachu/Mirakurun/blob/master/.github/CONTRIBUTING.md

に載っている。

mirakurun config [server|tuners|channels]でそれぞれ設定。

serverは初期設定のまま。

tuner。

- name: PT3-S1
  types:
    - BS
    - CS
  command: recdvb --dev 0 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S2
  types:
    - BS
    - CS
  command: recdvb --dev 2 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S3
  types:
    - BS
    - CS
  command: recdvb --dev 4 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S4
  types:
    - BS
    - CS
  command: recdvb --dev 6 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-T1
  types:
    - GR
  command: recdvb --dev 1 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false

- name: PT3-T2
  types:
    - GR
  command: recdvb --dev 3 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-T3
  types:
"/usr/local/etc/mirakurun/tuners.yml" 60L, 1127C
- name: PT3-S1
  types:
    - BS
    - CS
  command: recdvb --dev 0 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S2
  types:
    - BS
    - CS
  command: recdvb --dev 2 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S3
  types:
    - BS
    - CS
  command: recdvb --dev 4 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-S4
  types:
    - BS
    - CS
  command: recdvb --dev 6 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-T1
  types:
    - GR
  command: recdvb --dev 1 <channel> - -
  decoder: arib-b25-stream-test
  isDisabled: false

- name: PT3-T2
  types:
    - GR
  command: recdvb --dev 3 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-T3
  types:
    - GR
  command: recdvb --dev 5 <channel> - -
  decoder: arib-b25-stream-test

- name: PT3-T4
  types:
    - GR
  command: recdvb --dev 7 <channel> - -
  decoder: arib-b25-stream-test

- name: TBS6922
  types:
    - SKY
  command: szap-s2j -c /usr/local/etc/szap-s2j.conf -l <satelite> -S 1 -p -r -M 5 -C 35 <channel>
  dvbDevicePath: /dev/dvb/adapter0/dvr0
  decoder: arib-b1-stream-test
  isDisabled: true

recpt1の代わりにrecdvbを使うように変更。

channels。

うちのマンションはケーブルテレビでテレ玉チバテレビも入るので、チャンネルスキャンをする。

curl -X PUT "http://localhost:40772/api/config/channels/scan"

このコマンドを実行するとchannelsの設定が上書きされて空行などが消えるので注意。

Chinachu

Wikiのインストール手順の通り。

https://github.com/Chinachu/Chinachu/wiki/Gamma-Installation-V2

録画先を増設したHDDにして、ファイル名を<title> [<channel-name>][<date:yyyymmdd-HHMM>].tsにした。

http://サーバーのIPアドレス:20223を開いて、番組表が見られて、録画ができれば良い。 同じLAN内からは繋がる。

nginx

外からも操作できるようにしたい。 DDNSで自宅に繋がるようにはしている。

一応Chinachu単体でも、wuiUserswuiOpenServerwuiOpenPortを設定すれば外からアクセスできるのだが、廃止予定らしい。 nginxでリバースプロキシを立てる。

aptでインストールして、 /etc/nginx/sites-enabled/default を削除。 /etc/nginx/conf.d/に適当なファイル名で、

server {
  listen 80 default_server;
  location / {
    auth_basic "secret";
    auth_basic_user_file /etc/nginx/.htpasswd;
    proxy_pass http://サーバーのIPアドレス:20772;
  }
}

を書き込む。 htpasswd -c /etc/nginx/.htpasswd ログインIDでパスワードファイルを作成。

HTTPS

録画サーバーに平文で繋ぐのが憚られるような信用できないネットワークを使う機会があるか……?とは思うが、このご時世、webサーバーを立てたらHTTPSにもしておこう。

https://certbot.eff.org/

で、nginxとOSを選択。 出てきたコマンドを入力すると、証明書の取得、nginxの設定の変更、証明書の更新をcronに登録までやってくれる。 すごい。

Samba

メインのWindows PCから録画したファイルを見られるようにする。 sudo apt install sambaでsambaをインストールして、/etc/samba/smb.confに次の設定を追加。

[video]
  path = 録画ディレクトリ
  browsable = yes
  guest ok = no
  read only = no
  writable = yes

sudo smbpasswd -a ユーザー名

録画予約

この時期にいちいちアニメのタイトルを登録して、表記揺れに悩まされたりするのが面倒。 ジャンルアニメを全部録画したらどうなるのだろうと試してみたところ、1週間で1 TBくらいだった。 4 TBのHDDではちょっと足りない。 また、地上波と衛星波がそれぞれ4 chずつだと、数番組は予約が被って録画ができなかった。 ちまちまと登録するしかない。

テキストエディタに回転表示機能があったら便利なのではないか

C言語でこういうコードがあったとする。

int f(Z *z) {
    int result;
    W w;
    X x;
    Y y;
    Z z;
    result = hoge(&w);
    if (result != E_OK)
        return result;
    result = fuga(&w, &x);
    if (result != E_OK)
        return result;
    result = piyo(&w, &x, &y);
    if (result != E_OK) {
        /* piyoのエラーはログを出す */
        log("error in piyo !!!! code: %d, arg: (%s, %s)", result, W2str(&w), X2str(&x));
        return result;
    }
    result = hogera(&y, &z);
    if (result != E_OK)
        return result;
    return E_OK;
}

Erlangで同じコードを書くと、Erlangは途中でreturnすることができないので、こうなる。

-spec f() -> {ok, z()} | {error, term()}.
f() ->
    case hoge() of
        {ok, W} ->
            case fuga(W) of
                {ok, X} ->
                    case piyo(W, X) of
                        {ok, Y} ->
                            case hogera(Y) of
                                {ok, Z} ->
                                    {ok, Z};
                                {error, Reason} ->
                                    {error, Reason}
                            end;
                        {error, Reason} ->
                            %% piyoのエラーはログを出す
                            log("error in piyo !!! code: ~p, arg: (~p, ~p)", [Reason, W, X]),
                            {error, Reason}
                    end;
                {error, Reason} ->
                    {error, Reason}
            end;
        {error, Reason} ->
            {error, Reason}
    end.

ネストが深いし、関数の呼び出しとエラー処理が離れていて読みづらい。 returnのある言語でも、single-entry single-exitルールで書いていたり、JavaScriptのいわゆるコールバック地獄になったりすると、同じようになる。

エラー処理が離れている点については、エラー処理を先に書くという手がある。

-spec f() -> {ok, z()} | {error, term()}.
f() ->
    case hoge() of
        {error, Reason} ->
            {error, Reason};
        {ok, W} ->
            case fuga(W) of
                {error, Reason} ->
                    {error, Reason};
                {ok, X} ->
                    case piyo(W, X) of
                        {error, Reason} ->
                            %% piyoのエラーはログを出す
                            log("error in piyo !!! code: ~p, arg: (~p, ~p)", [Reason, W, X]),
                            {error, Reason};
                        {ok, Y} ->
                            case hogera(Y) of
                                {error, Reason} ->
                                    {error, Reason};
                                {ok, Z} ->
                                    {ok, Z}
                            end
                    end
            end
    end.

見た目も元のC言語のコードに近い。 ただし、ネストの深さは変わらない。 C言語では上から下に読めるが、Erlangでは左上から右下に読むことになる。

エディタがこのように斜めに表示してくれれば、ネストの深さの問題が解決する。

f:id:kusano_k:20180310171629p:plain