Let’s encryptとSSL/TLSに関する誤謬

全く以て意味不明な誤謬がはびこっていた上に、やたら上から目線だったので、消火しておこうと思う。

そもそもSSL, TLSとは何か

SSL/TLSは暗号化技術である。

SSL/TLSのデータ通信自体は対称暗号である。ただし、暗号化に利用する暗号鍵は使い捨てる。 Cipherはかなり色々使えるのだけど、だいたいはTriple DES (3DES)かAESが使われる。

その手順は

  1. <- HelloRequest
  2. -> ClientHello
  3. <- ServerHello
  4. <- ServerCertificate
  5. <- ServerKeyExchange
  6. <- ServerHelloDone
  7. -> ClientKeyExchange
  8. -> Finished
  9. -> ChangeCipherSpec
  10. <- Finished
  11. <- ChangeChiperSpec
  12. <-> Application Data

Key Exchangeというのは非対称暗号鍵の交換である。 これもその場で生成するもので、RSA/DHE/ECDHEのいずれかを使用する。

非対称暗号というのは暗号化する鍵(公開鍵)と復号化する鍵(秘密鍵)のペアからなる。 公開鍵では暗号化はできるが復号化はできないため、公開鍵は相手に渡してしまうことができる。 これを利用してKeyExchangeでそれぞれ公開鍵を送りつけるわけである。

RSAの場合はServer Certificateで送りつけたサーバー証明書に含まれるサーバー公開鍵を使って共有する秘密を暗号化して送りつけるだけだが(ServerKeyExchangeは省略される)、DHEの場合はちょっと複雑だ。

サーバーは共通値という値とキーペアを作成する。 そして、クライアントに対して共通値と公開鍵を送信する。

クライアントは共通値に基づいてキーペアを作成する。そして公開鍵を送信することで共有秘密値を算出できるようになる。

そしてお互いが共有秘密値に基づいて暗号鍵を生成する。同じ値から同じ方法で生成するのでサーバーとクライアント双方が同じ鍵を持っている状態となり、これにより対称暗号によるやりとりが行える。

証明書とはなにか

SSLに付属しているのが証明書、という概念である。

これは中間者攻撃を防ぐための仕組みで、サーバーの証明書に第三者が署名する。 サーバーの署名にはサーバーのドメインが含まれている。

これによってどうやって信頼を保つのか? これは、予め「信頼できる者」を決めて、その信頼できる者が署名したものは信頼できるという考え方だ。

悪意ある第三者が証明書を偽造しようとしても、サーバーのドメインを含んだ証明書を、「信頼できる者」は署名してくれない。 だから通信相手になりすまして情報を掠め取ろうとしても、信頼できる署名された証明書を送ることができず発覚する、というわけだ。

「信頼できる者」が実は信頼できない、ということはないのか?

答えは、ある。最近ではGoogleがセキュリティ企業大手のSymantec傘下の認証局が署名した証明書を信頼しない、と決めた。

ドメインの正当性の確認方法

サーバーの証明書に署名するには、署名を要求された証明書が間違いなくドメイン所有者のものであることを確認しなくてはいけない。

ではそれをどうやって確認するか?

方法は色々あるのだが、ドメイン所有の確認方法は現在はウェブを使う方法が一般的だ。 指定されたファイルを指定されたアドレスでアクセスできるように配置する。 本当にドメインの所有者であればそのドメインのアドレスでアクセスできる場所にファイルを配置することが可能だが、そうでなければそんなことはできない、というわけだ。

この方法は割と簡単で合理的だ。

DVとOV

さて、一般に使われている証明書はDVとOVがある。

DVというのはそのドメインの所有者であることを認めた署名だが、OVというのはそのドメインを所有する組織の実在を確認したものである。

これは登記簿を提出したりする。 まあ、ドメインの所有者情報と企業情報が一致することを確認するのだ。案外簡単に通る。

OVを取ると、FirefoxやChromeだと、アドレス左の鍵マークの右側に組織名が表示される。

で、OVのほうが価値がある、と言われるのだが。

  • あなたはその証明書がDVであるかOVであるかを確認しているか?
  • あなたはOVなら信頼するけどDVでは信頼しない、という対応をとっているか?
  • 「その企業は実在する」という情報は「その相手を信用する」に値する情報か?

私は意味がないと思っている。

SSLの良いところ

まず、計算量的安全性という意味からいえば、解読できるようになったとき解読できる量が少ないというのは計算価値を下げることになる。

さらに解読しなければならない鍵が増えると計算量自体が増えることになる。

SSLの悪いところ

技術に罪はないが仕組みが問題だった。

予め信頼できる者を決めてしまう。 もちろん、大手セキュリティ企業などだ。

するとどうなったか。

第一に、「ボロい商売」になった。

SSLはかなり重要な技術だ。 SSLの重要性は主には暗号化だ。盗聴の難易度と中間者攻撃の難易度はまるで違う。 盗聴はとても簡単だが、中間者攻撃はそうそうできない。 だから重要度としては中間者攻撃を防ぐことよりも盗聴を防ぐこと、暗号化することなのだ。

ところが、SSLの価値は証明書にあるように言われた。 当然だ。SSLの採用自体は別に「信頼できる者」の力は必要ない。 「信頼できる者」が証明書を売るためには「署名がないと危険です!!」というしかない。 実際、中間者攻撃を防ぐ仕組みがある以上、有効な証明書のない証明書は警告されることになる。

となるとSSLを使うためには署名してもらわなくてはならない、という図式ができあがる。 これを利用して高額で売りつけるわけだ。

ちなみに、現在署名の値段は年間8万円から22万円ほどである。 昔はもっとずっと高かった。

ビジネスでやっているのならできなくはないが、個人的にやっているだけのところでは使えるわけがない。

社会的に不可欠な技術であるにもかかわらず、SSLを使える者を限定する、という行為に走ったわけだ。

SSLの構造悪とLet’s Encrypt

このような問題への対応として、Let’s Encryptが誕生した。

セキュリティ的見地から言えば、重要なのは「高額なSSL署名を購入すること」ではなく、「社会的にSSLを使用すること」が重要である。 ウェブばかりが取り沙汰されるが、メールに至ってはSSL/TLSを使わなければパスワードも普通に平文で送りつけるのだ。

そこでMozillaやGoogleなどが主導してHTTPSを当たり前のものにするべく、誰にでも使えるSSL認証を開始した。 これがLet’s Encryptである。

Let’s Encryptは無料なだけではない。 簡便で、かつ透明性が確保されている、というのも特徴だ。

Let’s Encryptはルート認証局のIdenTrustによって署名されている。 これによりLet’s Encryptの署名は信頼できるものとして取り扱うことができるようになっている。

Let’s Encryptが信頼できない、という謎の誤謬

まぁ、根拠は全く不明だ。

Let’s Encryptではドメインが正当なものかどうかわからないだろ、と言ったりするのだが、 ACMEトランザクションは公開されているし、ウェブを使って自ドメイン上に指定ファイルを設置するのでドメイン所有は間違いなく確認できる。

むしろ証明書発行過程が不透明な他のDVよりもはるかに信用できると思う。

OVには劣る、というのはわかるが、そもそもOVを使っているところなんてとても少ないし、「DVだ!!信用できない!!!」という発言ではないので意味がない。 Let’s EncryptがDVとしての機能を満たしていないというのであれば、なぜ満たしていないのかぜひ私に説明してほしい。 もちろん、Let’s Encryptでドメイン所有を偽る具体的な手法を、だ。

基本的には、「○○が署名したやつがいいんだ、Let’s Encryptなんて格が低い!!!」みたいな、SSL証明書にワインのような味わい深さを求めているか、あるいはたくさんお金を出すと偉いとか安心できるとか考えている人だと思う。 いずれにせよ、権威主義なのではなかろうか。

ところで、Let’s EncryptはIdenTrustが署名しているのだけど、IdenTrustは信用できない、という発言なのだろうか? そうなると、Let’s Encryptに限らず相当たくさん敵を作ることになると思うのだけど、アメリカのことだから別にいいや、ということだろうか。

署名と検証

原典で「証明書の確認でパフォーマンスが」という発言がある。

基本的には、証明書には証明あるいは署名の有効期限がある。 切れたら再取得する。新しいものがあれば更新するし、なければ失効したということで信頼できないとみなす。

実際には「署名したけど不正がみつかったので取り消す」ということがあるので、もうちょっと頻繁に取りに行く。

検証するためにサーバーに問い合わせる必要は全くない。 なぜならば証明書が正しいかどうかは手元にある公開鍵で検証できるからだ。

目的を思い出せ

DV証明書を用いたSSLの目的は

  • 安全な暗号化を行う
  • サーバーがドメインの所有者であることを確認する

の2点である。

別にその相手が信用できるかとか、そんなことは関係ない。 というか、そんなことはむしろOVによって確認されるように企業が実在したところで信用できるかどうかとは関係ない。 実在するけど健全じゃない企業なんてたくさんあるだろう?

Let’s Encryptはこれを満たしているはずだし、これを採用しない、 つまり暗号化を行うことも相手を確認することができない状態よりもずっと良いはずだ。

Let’s Encryptが他のDVに劣る点は一体なんだろう? 私には全く想像もつかない。

残念ながらLet’s Encryptは駄目だと言っている人が、この2点を満たしていない具体的な根拠を示しているのは見たことがない。

認証について指摘があったので重ねて

example.comの証明書に署名をもらおうとすると、Let’s Encryptは「http://example.com/abcdefgとしてこのファイルをダウンロードできるようにしてください。ダウンロードできたら署名します」と求めると同時に、配置するための一時ファイルを送ってくる。

Let’s Encryptからファイルをもらう方法はHTTPSである。

Let’s Encryptが署名で保証しているのは、これを通過できた、という点に尽きる。

「Let’s EncryptのDNSを偽れたらどうなんだ」

という点については、まぁ、ものすごくハードルが高いので、完璧ではないけれど標準的にはとりあえず良しとできると思う。 そもそもそんなことはすぐバレるし、バレたら即座にLet’s Encryptの証明書がBANされることになるので、まぁ、大丈夫だろう。

そもそもSSLは暗号化が本筋であって、証明書が本体ではないので、そこに完璧を求める気もない仕様だ。

これは「DV一般の中でLet’s Encryptが駄目だという誤謬」に言及しているのでDV自体に問題があるという点については述べていないのだが、その場合はどう判断するか、ということについて言うと、 DV一般に不十分だとしたら(私はむしろそう考えている)、「SSLって駄目だよね」という話なので、認証が十分かどうかを論じる必要もない。そうなったらむしろSSLで十分かを論じることになるからだ。

他のDVの確認方法がどうなのか…という点については、全く標準化されておらず、手続きも事業者によって違うので、 ザルなところもあれば厳しいところもある。ただ、ACMEはその中では割と偽るハードルが高い(ただし、現状ではその価値も高いけれど)ことと、手続きの透明性が確保されていること(不当なドメインでないかをどうやってちゃんと確認してるのかよくわからないところもある)を考えれば 相対的には Let’s Encryptは悪くないと思う。

個人的な意見だが、SSLの証明書はお墨付きを与えているように感じる。 ドメイン自体に問題がある(例えばフィッシングドメインなど)場合でも正当な証明書は取れるわけで、そこで安心感を持ってしまうリスクを考えれば、「証明書の署名を必須にしてDVなんていう仕組みを導入したこと自体が失敗だったのではないか」と感じる。 「クレジットカードをとるようなところは取得した者を明らかにする」みたいなOVを拡張したような方式をオプショナルに採用すればよかったのではないか。

SSLの証明書の方式に問題があるということは、私は15年は言い続けているけれど、その話は長くなるので略。

SSHはSSLじゃない

SSHはSSとついているせいか、SSLを使っていると思っている人が結構いるようだ。

SSHはSSLを使っていない。別物だ。

ただし、SSH2では鍵交換の方法としてDHEを使っている。 非対称暗号でセッションを開始し、対称暗号でやりとりを暗号化する方式も同じだ。だから、似てはいる。

なお、鍵ログインに使用するRSA/ECDSA/Ed22519の鍵は通信の暗号化で使うわけではなく、通信を暗号化したあとにホストの真正性を問うために使う。

SSHでもPKIを使用した認証が行える、という話もあるのだけど(SSLと全く同じ方式)、これは私が見たことがないのでわからない。

参考文献

Qiitaでかなり詳しい記事を見かけたので参考にしてほしい。

Linux: 特定のアドレスに到達しないことを明示する (route/ipコマンド)

open-iscsiを用いたiSCSIイニシエータの場合、iSCSIターゲットが複数のIPアドレスを持っているとMultipathによってその全てのアドレスで接続しようとする。

だが、例えば192.168.1.0/24に属するコンピュータで、192.168.1.0/24, 192.168.2.0/24の両方に属しているNASを使おうとすると、192.168.2.0/24に対する経路がなければタイムアウトするまでひどく待たされることになる。 デフォルトゲートウェイ経由で192.168.2.0/24に対するパケットを投げ続けるためだ。

そこで、このコンピュータは192.168.2.0/24には通じていないことを明示して、即座に失敗させたい。

これはネットワークマネージャの設定では行うことができない。 コマンドで行う必要がある。

routeコマンドに関してはManpageに書いてあるのでわかりやすい。

# route add 192.168.2.0 netmask 255.255.255.0 reject

だが、Arch Linux系列のディストリビューションで標準採用されるipコマンド (iproute2) のほうは1Manpageがものすごく読みにくい上に日本語訳もされていないのでちょっと大変だ。 ipコマンドの場合は次のようにする。

# ip route add prohibit 192.168.2.0/24

これにより192.168.2.0/24に対する接続はそもそも禁止されることになる。

% ping 192.168.2.64
Do you want to ping broadcast? Then -b. If not, check your local firewall rules.
% telnet 192.168.2.64
Trying 192.168.2.64...
telnet: Unable to connect to remote host: 許可がありません

  1. そもそもrouteやifconfigなどを使わず、iproute2(ip)を使うということをどれくらいの人が知っているのだろう? arp, ifconfig, iwconfig, nameif, netstat, route を兼ねる仕組みになっており、Manjaro Linuxではこれらのコマンドは標準では入っていない。 digやnslookupも含まれておらず、getentを使用する。↩

一連のサーバー&SSH技 応用・実用編

このブログは多くが検索によって解決法を探してたどり着いた読者に支えられている。

このような場合、その人が向いている方向としては二種類ある。

ひとつは、なにをしようとしているかが(適切かはどうかはともかく)決まっている場合だ。 ポートフォワーディングしたい、とか、SSHでなんとかならないか、とか、自分の中で絞り込みができている場合である。

もうひとつは自分の現状だけを認識している場合だ。 例えば「ストレージがいっぱいなった」とか、「家のデータに外からアクセスできなくて不便だ」とか。 どのような解決方法があるのか、あるいは解決可能なのかどうかから探している状態だ。

このふたつは明確に異なる。

前者であればポイントを絞った答が欲しい一方、自分の中にある前提が間違っていると解決まで回り道をすることになる。 後者であれば何をどう考えて調べればいいのか絞り込んでいくほうが難しい。

しかし前者の問題は解決できるのだが、後者の問題は解決できない、という人が割と多い。 問題を定義し、設計し、手法を構築することは地力が求められ、知識の体系化が進んでいないために発想力が求められると難しい、というケースだ。

そこで、今回はそのあたりに踏み込んで解説していく。

個別ケースや個々の人の理解に合わせた内容は仕事としてやっているので、興味があればのぞいてみてほしい

Overview

Definition

親と同居しているごく普通のLinuxer少女が、日々を便利にするために奮闘する姿でも描けばよい。

…と思ったのだが、VPSを用意するにあたりクレジットカードが必要になるあたり、やはりペット同居のごく普通の乙女、もちろんLinuxerである、ぐらいにとどめておくのが無難か。

phase 1

ストレージの不足を解消するためのNAS導入と、監視カメラの設置を行う。

スマートフォンはきっと愛猫の写真と動画でいっぱいなのだろう。 これに愛猫が勝手にツナ缶を空けて食べてしまわないかチェックしておく必要がある。

phase 2

NASに写真を保存するようにしたはいいが、このままでは仕事中に愛猫の写真を堪能できない。

24時間愛猫とたわむれるためには家にあるデータにもアクセスできなくてはならない。

phase 3

もし愛猫がトラに進化しそうなときには急いで家にかえりこれを阻止しなくてはならない。

また、愛猫がNASからハードディスクを取り出そうとしたときにはデータ保護のためにNASを緊急停止する必要があるはずだ。

構成と発展

予めお断り

コピペでできるようにすることを目標としているわけではないので、詳しい手順などは各自学んでほしい。

難しい部分は過去の記事で解説している。

家用コンピュータを導入する

この手順において一番最初に、そして独立して効果を発揮するのはNASなのだが、設定なども面倒なので、とりあえずコンピュータを用意しよう。

この段階でラップトップがあるのであれば、NASがさき、デスクトップは後でも構わないし、 この場合必ずしもデスクトップである必要はない。 だが、総合的に考えてよりよいコンピュータ環境を構築するのが目標なので、このような余剰部分も今回は入れていく。

さて、やはりコストパフォーマンスを考えても、デスクトップPCは性能が高い。 そこでデスクトップを導入することにしたいが、おしゃれに気を使う乙女としては部屋にあまりに無骨な機械を導入するのは気が引ける。 かといってせっかくコンピュータを導入するならいろいろしてみたい。 悩みに悩んだ彼女は神に問うた。天の声(はるか)はこう答えた

「Pavilion Waveあたりにしとけば?」

まじめに答えて、まじめに構築する話はそのうちMimir Yokohamaでやることにしよう。

NASを導入する

NASの導入と構築もそのうち向こうでやることにする。 今回はLinuxでのテクニック中心なので、簡単に。

ReadyNASあたりが鉄板だろうし、WebDAV(HTTP)で共有すればスマートフォンのデータを転送するのも簡単だ。

もう少しスマートな話をすると、まずはReadyNASでストレージ環境を作り、共有の作成まで進める。 共有をSMBにして、

# mount -t cifs //nas-aa-bb-cc/shared1 /srv/nas

のようにマウントする。

次にスマートフォンをLinuxデスクトップに接続し、MTP経由でデータをコピーする。 あとは

$ rsync -rv ~/Pictures/20180602 /srv/nas/

のようにして(/の有無に注意)コピーすればバックアップが確保された状態になる。

監視カメラを導入する

これはどちらかといえばSocks Proxyの説明のためなので詳しくは省くけれども、ウェブカムとmotionを使うのが定番。動体検知もできる。

これについては結構設定が色々ややこしい。 興味がある人は“Linux motion カメラ”で検索すれば色々でてくるので参考にすれば良い。 設定ファイルを眺めるのも悪くない。

ネットワークに接続する

NASを導入する時点で有線でのネットワークは構築されているはずだが、無線LANルーターを含めて、さらに 有線での インターネット接続環境を構築する。

VPSを契約する

私はConoHaのとServerMan@VPSのユーザーだが、さくらのVPSも結構定番。

今回はゲートウェイとして使うだけなので、最低限でも大丈夫でSSH接続だけできるようにすればよいが、発展的にはあまりおすすめできない。

VPSを契約したらサーバーを設定し、SSHログイン可能な状態にしておく。

ラップトップを買う

外からアクセスできるコンピュータが必要である。 ラップトップを買おう。ネットカフェのような環境からアクセスすることを考えるべきではない。

SSHを設定する

ラップトップで2つのSSH鍵を作り、それぞれデスクトップとサーバーのauthorized keyとして登録する。

制限をかけてもいいが、今回の場合鍵のパスワード保護が可能なため、特にかけないほうが良いだろう。

ラップトップ側の~/.ssh/configは設定が必要。

Host vps
  User jrh
  Port 22
  HostName vps.example.com
  IdentityFile ~/.ssh/vpslogin_rsa

Host target-proxy
  User jrh
  Port 10000
  HostName localhost
  IdentityFile ~/.ssh/proxylogin_rsa
  ProxyCommand ssh -CW %h:%p vps

この場合、VPSのログインしてからリバースプロキシを介してデスクトップにログインする。

localhostはVPSから見たlocalhost(VPSのlo)だが、デスクトップにログインするためのSSHを実行するのはラップトップである。

単純にログインしたあとログインする場合、デスクトップにログインするSSHを実行するのはVPSなので、これがProxyCommandの特徴となる。

単純にSSHを張るだけであればデスクトップからVPSにログインできるようにして、

$ ssh -R 22:localhost:10000 vps

のようにすればよいのだが、経験ではそれはうまくいかないのでそれは記事にした

外から家のデータにアクセスする

これでSSH経由でアクセスできるようになったので、デスクトップでNASをマウントしておけばデータは利用可能な状態になる。 Nemo, Thunarならばアドレス欄にsftp://target-proxy/と入力すればアクセス可能。NautilusならConnect to Serverから。 Dolphin/Konquerorにも同等の機能はあるのだが、うまく動作しない場合がある。

VPSのコンソールやmotionのストリーミングにアクセスする

VPSのコンソールなどWebインターフェイスをもつものについてはインターネットに公開するべきではなくインターネットに閉じておくべきだが、これでは外出中にコントロールできない。

だが、SSHでアクセスできる状態であれば、簡単に解決できる。

$ ssh target-proxy -NCD 8888

Chromiumが簡単。

$ chromium --proxy-server="socks://localhost:8888"

Vivladiでも良い。

$ vivaldi-stable --incognito --proxy-server="socks://localhost:8888"

Firefoxなら専用プロファイルか

$ firefox -P proxylogin

【注意】 Arch/Manjaro 最新 open-iscsi パッケージにバグ

Arch / Manjaro Linux の最新 open-iscsi パッケージをインストールすると、 libopeniscsiusr.so.0.1.0 というライブラリが欠如しているためにiSCSIが動作しなくなる。

システム構成の中核部に採用している場合はシステムが利用できなくなるため要注意。

有志がAURのgitバージョンからビルドした2.0.876-2をアップロードしており、このパッケージはManjaroでもそのまま動作する。

Linuxで プロセスごとにネットワークを禁止 / インターフェイスを限定

特定のプロセスをオフラインにする

稀にネットワークを禁止した状態で利用したいことがある。 例えば安全性に疑問があるケース、無用な通信が疑われるケース、ファイルをダウンロードできているかの確認などだ。

方法としては

  • cgroupsを使う
  • iptablesを使う (EUID/EGID単位なら制御可能)
  • SELinux + iptables を使う

の3種類。

単純にネットワークを利用できないようにするのはunshare

$ sudo unshare -n w3m /some/text/file

環境変数とかXAuthorityとか面倒なので、Firefoxなどを実行するならsudoでrootにしてsudoで戻すのが勧め。

特定のプロセスを特定のゲートウェイから流す

これだけだと「なんだよ」とか言われてしまうので、もうちょっとまともな話をしよう。

SSH+pppdを使ったVPNは比較的知られているが、VPNはプロキシを通すのに使うか、デフォルトゲートにしてしまうかというのが一般的で、プロセス単位でVPNにルーティングする方法というのはあまり知られていない。

しかしこれもcgroupsを使って実現可能だ。

ここではiptablesによるルーティングを目的とした仮想インターフェイスやブリッジを使うのではなく、あくまで既に割り当てられているインターフェイスを使用させることを目的とする。

まずはトンネルを通しておく。

# pppd updetach noauth silent nodeflate pty "/usr/bin/ssh root@gwhost /usr/sbin/pppd nodetach notty noauth" ipparam vpn 10.0.8.1:10.0.8.2

専用に名前空間を作り、pppデバイスを登録する。

# ip netns add vpnns
# ip link set ppp0 netns vpnns

pppデバイスにアドレスを与える。 pppは/32プレフィックスがつくのだけど、/32だと通信できないので、/24にしておく。

# ip netns exec vpnns ip addr add 10.0.8.1/32 dev ppp0

これで10.0.8.2とは通信できるようになった。 あとはこの状態でシェルを立ち上げ

# ip netns exec vpnns bash -l

お好きにどうぞ。

SSH+pppdのトンネルをデフォルトルートにするのはなかなか苦労がある。 もし単純に物理的なインターフェイスをデフォルトルートとして使わせたいのならDHCPが使えて楽。

# ip netns exec newns dhcpclient eth1
# ip netns exec newns bash -l

もっと簡単な方法

SOCKSを使えばもっと楽にできる。

$ ssh -NCD8080 proxyhost

単純にSOCKS5プロキシとしてlocalhost:8080を指定すればOK。SSH経由で流れてくれる。

SOCKSに対応していないプログラムでも、proxychainsやtsocksを使えばできる場合も多いだろう。

プロセスごとに帯域制限を

cgroupsとtcを使ってください。

現状では理想的に動作しないのでこの話は略。 情報はここらへんにある。

ThinkPad E440がスリープから復帰できない問題 (機種固有)

ThinkPad e440は基本的にLinuxではスリープ/サスペンドからの復帰が全くできない。 スリープに入る段階でフリーズしてしまうため、スリープはできるのだけれども、電源再投入ができなくなる。 ちなみに、Windowsでもやや不安定で復帰できないことがある。

Linuxのスリープというのは結構複雑な問題で難しく、調整が必要なことは珍しくないのだが、それでもなかなかうまくいかず、 しかしe440の出番がそれほど多くないことから放置していた。 そもそも私がスリープをほとんど使わないという理由も大きい。

ただ、最近不便を感じ始めていたので対応することにした。

ArchWikiには機種ごとの情報があったりするので調べてみたところ、e440のページもあった

のでこれに基づきBIOSのアップデートを試みる。 現在の最新バージョンは2018-03-06のv.2.27で、ArchWikiの記述と異なりISO配布されているため特別なツールは必要ない。

アップデートしたところ何の問題もなく復帰できるようになった。 なんのこっちゃ。

今更だけど、mpvがビデオ再生に便利

mpv、ほんとになんでもできるようになってきていて笑いが止まらない。

mpvで自由自在にビデオを見る

mpvの定番の設定になっているようだけれども

ビデオを回転させる:

Alt+RIGHT add video-rotate 90
Alt+LEFT add video-rotate -90

ビデオをズーム/パンする。 これは既にデフォルトの設定として採用されている。

Alt+- add video-zoom -0.25
Alt+= add video-zoom 0.25

ズームしたビデオを移動する。

Alt+j add video-pan-x -0.05
Alt+l add video-pan-x 0.05
Alt+i add video-pan-y 0.05
Alt+k add video-pan-y -0.05

ズーム/パンの設定をリセットする。

Alt+BS set video-zoom 0; set video-pan-x 0; set video-pan-y 0

もちろん、こんなのはほんの一部で様々なことができる。

12はコントラストに割り当てられている。 全体的に画面が暗く、もやもやしてよく見えないときにはコントラストを上げると良い。 逆に色彩鮮やかすぎて目が痛い画面ではコントラストを下げると見やすくなる。 くらい室内の動画や夜間撮影の動画ではコントラスト上げが、明暗差がきつい晴天時のオンボード動画などではコントラスト下げが活躍する。

Ctrl++Ctrl+-はオーディオディレイに対応している。 定量的な音ズレを簡単に補正できる。

*/あるいは9, 0はボリュームコントロールに対応している。 複数のビデオを並行で再生するような環境では1音量を揃えるために活躍してくれる。セッションを越えて保存されないので、一時的な変更には最も手軽だ。

sでスナップショットを取る。非常に手軽だ。

3, 4でブライトネス、5, 6でガンマ、7, 8でサチュレーションを補正する。 私はあまり使わないが画質的に見づらい動画を補正できる。

iでビデオの詳細な情報を表示する。 詳細な上にみやすく、ビデオソースについて知る必要があるときには活躍する。

lでA-Bループになる。lを押すだけの簡単操作で正確なタイミングをつかみやすい。 Lでそのビデオをループする。

aはアスペクト比の強制を行う。 アスペクト比の間違ったビデオを再エンコードせずに視聴できる。

字幕も表示/非表示、タイミングの補正、位置の補正も可能だ。

mで一発ミュート。

[]は再生速度のコントロールになっている。 音楽の練習ではとても重宝する。

Ctrl+LEFTCtrl+RIGHTはちょっとめずらしい、字幕の早送り/巻き戻しに対応している。密度の高い字幕がある場合には結構便利だ。

PgUpPgDownがチャプターに対応しているが、Shift+PgUpShiftPgDownが10分巻に対応しているのも数時間あるようなビデオではポイント高い。

そして、実はXF86メディアキーでの操作も可能。

ほんとなんでもできる。ありとあらゆるビデオを快適に再生し、活用できるようになっている。

mpvについて

mpvはもとはMPlayer2と呼ばれていて、MPlayerからフォークしたものだ。 MPlayer2はあまり人気がなかった気がするけれども、mpvになってからはMPlayerに対する明らかなアドバンテージの数々(例えばVA-API/VDPAUのサポートなど)を武器に今や標準ツールとなりつつある。

MPlayerもそうなのだけど、GUIのないビデオプレイヤーの魅力って、ちょっと理解しにくい。 実際、私も昔はGMPlayer2ばかり使っていた。

ないよりはあったほうがいいじゃないか、と思うかもしれない。 だが、そうではないのだ。

ビデオの場合、視覚的なものである。 コントロールを表示すればその分表示領域が必要になる。 画面の外に表示すればビデオは小さくなるし、重ねれば邪魔になる。必ずしもフルスクリーンで見るわけでもない。フルスクリーンではないけれど取れる範囲で最大限のスペースを使いたいという希望は普通にあるだろう。

また、VLCやSMPlayerだとビデオを開くたびにセッションを開く。 再生が重いというのもあるが、ものすごく単純なこととして、「ファイルを開いたら単純にそのファイルを開いてほしい、それ以外にはなにもしないでほしい」というのがあったりする。

mpvは再生によって何かを保存したり記憶したりしない。 余計なものを開いたりもしない。ファイルブラウザでビデオを開くアプリケーションをmpvにしていれば、ただ単純にダブルクリックするとビデオが再生される。

だが、その場合でもちゃんと視聴に必要な機能は備わっていてほしいはずだ。 mpvには他のプレイヤーにはないような機能まできっちり備わっている。 何かにプレイヤーを内包するような機能はない3が、プレイヤーとしての機能はパーフェクトなはずだ。

写真で考えてみよう。

アルバムアプリを立ち上げ、写真フォルダを探しながら写真をみるときと、ファイルブラウザから写真をダブルクリックするときでは意識に大きな違いがあるはずだ。 そして、ファイルブラウザでダブルクリックしたとき、アルバムアプリが立ち上がり、写真フォルダ一覧が表示されるのはあなたが望むことではないだろう。ファイルブラウザで写真をダブルクリックしたら写真を表示してほしいはずだ。それ以外の余計なものは表示せずに。

mpvはそういうアプリケーションだ。 コントロールはキーボードで行う。一見複雑なようだが、考えてみてほしい。 複雑に様々なコントロールができるとしたら、専用のリモコン、あるいはコントローラがあったほうが便利だろう。

だが、GUIがあったほうが便利なこともある。 例えば全体がどれくらいで、今どれくらいの位置を再生しているのか知りたいときなどだ。 mpvはpseudo-gui/OSDと呼ばれる機能により、oキーと、マウスオーバーによってそれらの情報を表示できる。 しかも表示できるだけではない。なんて操作できる。ビデオスキャンのほか、タイトルクリックでのフルタイトル表示、プレイリストコントロールなどが可能だ。


  1. 多分そんなことをする人はあまりいないのだけれど、私は多用する。↩

  2. ソフトウェアとしてはMPlayerなのだけれど、gmplayerというコマンドを使用するとGUIつきで起動する。Arch LinuxではMPlayerはgmplayerなしでビルドされている。↩

  3. いや、実はyoutube-dlを介してURL再生できたりするのだが↩

SSHのリバースポートフォワーディングの強化

以前かなり入念に設定して外出中もSSHでログインできるようにしたはずだったのだが、実際に試してみるとうまくいかないケースがあった。

もちろん、前回の設定で、SSHが死ねば再度コネクションを貼り直すようにしたし、サーバーから一定時間応答がなければ死んだとみなすようになっていた。 これで万全のはずだった。

ところが、サーバーからPONGは届いているにもかかわらず、ポートフォワーディングは死んでいる…という事態に遭遇したのだ。

これでは困る。 なぜそんなことになるというのか。

しかし発生するものは仕方ない。 実際にログインできない場合には無理やり貼り直すことにしよう。

方法としては割と単純で、自分自身に対するものではあるが、一旦サーバーにSSHで接続し、そこからSSHで手元のコンピュータに対してログインしコマンドを実行する。 これに失敗すればコネクションが切れているとみなす。

ProxyCommandを使う必要はなく、単純にsshのコマンドとしてsshを含めればいい。

新しく鍵を作ってサーバーに登録する。

サーバーで実行するコマンドはsshである。

また、逆にサーバーでも新しい鍵を作って手元コンピュータに登録する。つまり、互いにコマンド実行用の鍵を登録することになる。

サーバー側で結びつけるコマンドはsshである。 このSSHで~/.ssh/configによってターゲットコンピュータに対してログインするホストを指定する。

Host target-pc-connection-check
    User jrh
    Port 2222
    Hostname localhost
    IdentityFile ~/.ssh/target-pc-connection-check_rsa

サーバー側で鍵に結びつけるコマンドはssh target-pc-connection-checkである。

ターゲット側では次のように登録する。

Host target-pc-connection-check-via-server
    User jrh
    Port 22
    Hostname serverhost.example.com
    IdentityFile ~/.ssh/target-pc-connection-check-via-server_rsa

これでターゲットコンピュータがこの鍵でサーバーにログインすると自動的にサーバーはSSHを実行しターゲットコンピュータにSSHポートフォワーディングを介して接続しようとする。 自動化のためそれぞれの鍵にはパスワードはかけない。

ターゲット側で鍵に結びつけるコマンドはtrueでも良いと思うが、echo OKあたりでも良いだろう。

これでターゲット側から

とすれば、コネクションが到達するかどうかをチェックできる。

Systemdユニットに組み込むと面倒なことになるので、システムトレイアプリに組み込む。

ArchLinux * Nginx * php-fpm * MariaDB * WordPress

慣れている人にとっては常識レベルなのだろうけれど、つまずきどころ満載だったので、メモ。

Nginxのインストール

# pacman -S nginx

PHP / php-fpmのインストール

# pacman -S php-fpm

MariaDBのインストール

“MySQL”と認識している人も多いだろうけれども、 現在は圧倒的にMySQLよりMariaDBが一般的である。

MySQL自体は継続しているが、MySQLを提供しているディストリビューションは非常に少なく、 そもそもアプリケーションが想定しているデータベースもMySQLよりMariaDBのほうが一般的だ。

MariaDBはMySQL5.5から派生したコミュニティベースのデータベースである。

# pacman -S mariadb

有効化する前に 初期設定を行う。

# mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql

そしてセキュアな設定を行う。 (省略しても構わない)

# mysql_secure_installation

リモートホストからのアクセスを拒絶しておく。 /etc/mysql/my.cnfskip-networkingをアンコメントすればOK。この状態でもローカルホストからは接続できる。

これでMariaDBを起動・有効化できる。

PHPの設定

PHPのモジュールが無効になっているので有効にしておく。 これがなければデータベースに接続できず、500 Internal Server Errorになる。

/etc/php/php.iniを編集する。bz2, mysqli, pdo_mysqlを有効にする必要がある。

これをしていないとWordPressの初期設定でデータベース設定後に500エラーになることになり困惑することになる。

これでphp-fpmを起動・有効化できる。

Nginxの設定

まずはサーバー設定を書いておく。 設定を書かない場合、WordPressにアクセス自体できない。

どこに何を書くかという解説はしない(Nginxについて説明をはじめると長い)ので、それを理解しているという前提で進める。 もしろん、コピペでなく値は合わせること。

最低限だとこんな感じ。

server {
  listen 80;
  listen [::]:80;
  server_name blog.example.com;
  root /srv/http/blog/example.com;

  access_log /var/log/nginx/blog-example.log;

          location / {
               index  index.html index.htm index.php;
          }
          location ~ \.php$ {
               fastcgi_index  index.php;
               include        fastcgi.conf;
          }

}

公式の設定から引用するとこんな感じ。

server {
  listen 80;
  listen [::]:80;
  server_name blog.example.com;
  root /srv/http/blog/example.com;


  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  rewrite /wp-admin$ $scheme://$host$uri/ permanent;

  location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 24h;
    log_not_found off;
  }

  location ~ \.php$ {
    try_files $uri =404;
    
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include fastcgi_params;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#   fastcgi_intercept_errors on;
    fastcgi_pass php;
  }

}

公式の場合サイト別ではなく上流で次のような設定も必要になる。

upstream php {
  server unix:/run/php-fpm/php-fpm.sock;
}

php-fpmのソケットファイルが間違っている場合、502 Bad Gatewayになる。

WordPressのインストール

「公式パッケージはあるけどWordPress公式からインストールしたほうがいいよ」というのがArchの姿勢。

$ cd /srv/http
$ wget https://wordpress.org/latest.tar.gz
$ tar xvzf latest.tar.gz
$ sudo chown -R http:http wordpress
$ mv wordpress blog/example.com

パーミッションが間違っていると403 Forbiddenになる。 これは主に所有者で、Nginxプロセスの所有にする必要がある。 現在のArch LinuxではNginxプロセスはhttp:httpで動作する。

起動と有効化

# systemctl start nginx
# systemctl enable nginx
# systemctl start mariadb
# systemctl enable mariadb
# systemctl start php-fpm
# systemctl enable php-fpm

php-fpmが起動されていない場合は502 Bad Gateway、MariaDBが起動されていない場合は500 Internal Server Errorになる。

別のWordPressから移行する

WordPressのファイル側にもファイルがあるらしい(どうも画像データはこっちらしい)ので、MySQLのエクスポートと同時にファイルもとっておく必要がある。

取得したファイルはWordPressインストールの代わりに展開し、パーミッション(所有者)を変更する。 パーミッションの変更は忘れがち。

SiteGuardでログインアドレスを変更している場合は、この機能がApacheに依存しているためログインできなくなってしまうので、wp_content/plugins/site-guardを削除しておく。あるいは、エクスポート前にこの機能を無効にしておいてもいい。 ログインページをNginx上で変更したい場合は他のプラグインを仕様する必要がある。私の場合は“Login Rebuilder”を利用した。

従来が第三者サービスなどによって提供されていたWordPressで、データベース名やユーザー名が好ましくない場合、あるいは複数サイトをインストールするために指定したい場合はwp_config.phpも編集。

データベースをインポートする前にデータベースを用意しておく。

# mysql
> create database <database_name>
> create user '<username>'@'localhost'
> grant all privileges on <database_name>.* to '<username>'@'localhost' identified by '<password>'
> quit

そしてインポート

# mysql <database_name> < wordpress_database_file.sql

そんなわけでブログ引っ越し完了

ブログはXdomainの付属サービスから自サーバーに移動した。

これによりパフォーマンスが改善し、またスマートフォンでの閲覧において広告がでなくなった。

パフォーマンスは最善ではない。これはこのサーバーでWordPressだけが動いているわけではないため、リソースをWordPressに大量に割くことができないからだ。 必要ならば将来的にWordPressを独立したサーバーにしてパフォーマンスを向上させたり(Kasanagi導入が妥当だろう)、リソースを増強してパフォーマンスチューニングを行うかもしれない。

現状ではこのChienomiのほうのデイリーPVは1500から6000程度である。 特に広告などを出して収益があるわけでもないので、今のところあまり考えていない。 そうね、ヒューマンユニークがデイリー1500を越えるか、月間1000円以上の広告収入が発生するようなことがあれば考えようかな。

いずれ広告を出す可能性があるにせよ、それはChienomi側で選定しコントロールした話であり、プロバイダー広告が出るのは(広告を出さないというポリシーに基づく)ユーザービリティ的にもパフォーマンス的にもデメリットしかないので、Chienomiがそれなりにアクセスがあることを踏まえて対応した。

VPN(リバースフォワーディング)をアイコン操作にしてみる

先日の多段SSHによる外出時のログインだが、外出時にリバースフォワーディングをオンにし、帰ってきたらオフにするのはちょっと面倒だし、忘れそうだ。 そこで私は「システムトレイにアイコン出してもらって、クリックしたら閉じてくれるようにしたらいいじゃない」と考えた。

まず、「Linuxでシステムトレイにアイコン」と考えたらまずYadを考えて良い。 ZenityやKDialogはシステムトレイをサポートしていない。

yad --notification --image=<icon> --title=<title on hover>

の形式でシステムトレイにアイコンを表示できる。 --commandオプションをつかってクリック時の動作を指定することもできるし、--menuオプションで右クリックに対応させることもできる。 --commandオプションを指定した場合は終了するかわりにそのコマンドを実行する。

今回の場合クリックしたら終了を含む動作をさせたいので、特にコマンドは指定しない。 そこでyadプロセスが終了したらクリックした後の動作をさせていけばよいわけだ。

必ずしもこの操作をこのプログラムから行う、という制約はないこと、 そして「トンネルを解除しない」という選択がありえることから、ループとし、当該ユニットが動作中であればアイコンを表示する方式にした。

ひとつめのyadはシステムトレイにアイコンを表示し、クリックされるのを待つものだ。 これでクリックされるまではスクリプトはここでブロックされる。

ふたつ目のyadだが、yadの場合zenityと違い、タイプを指定しないで起動するとシンプルなダイアログになる。 アイコンとボタンのタイプはそれぞれ指定できる仕組みだ。 このため、ZenityやKDialogにあるいくつかの動作オプションがまとめられている。 ここではYes/Noダイアログを表示している。

なお、ボタンはボタンのあとに終了コードを書くようになっており、gtk-cancelも利用可能。それ以外は単にラベルとして使用される。

さらにランチャーで使用するため、.desktopファイルも作っておいた。 右クリックでの開始/停止もサポートしている。

これでわかりやすく、操作しやすくなった。

もちろん、SSHフォワーディングを行うスクリプトに含めるというのも手だが、そうすると他の手段が失われてしまう。 Systemdユニットにした上で追加機能は別のスクリプトにするというのは良いアイディアだと思う。