rsyncでバックアップするだけの接続を許可する

バックアップを保存するサーバ(以下バックアップサーバ)からバックアップしたいデータがあるサーバ(以下対象サーバ)にrsyncで安全に接続したいが、バックアップサーバから対象サーバをフル操作させるのはいや、というときにどうすればいいかを調べた。

とりあえずこれを見つけたのだが、説明不足で具体的になにやってるのかがさっぱり。

qa.atmarkit.co.jp

/usr/bin/rsync --server --daemon --config=$HOME/etc/rsyncd.conf .

とかどこから出てきたのかさっぱりだし。

また対象サーバが非rootという制限もあったのだが、その辺行けるかも不明だった。man rsyncを軽く漁った感じだとポートは873だとかいう話だし。

仕方ないのでいろいろ自分で調べた。まだいまいち理解しきれていないが、とりあえずメモっておく。

バックアップサーバから

rsync --rsh=ssh HOSTNAME::MODULE_NAME BACKUP_DIR

あるいは、

rsync --rsh=ssh rsync://HOSTNAME/MODULE_NAME BACKUP_DIR/

を実行する場合、

ssh HOSTNAME rsync --server --daemon .

上記のコマンドで接続される。ので、

rsync --server --daemon .

部分をauthorized_keysで許可すればいいという話。この接続コマンドは、rsync-vv渡して試せば確認できる。

そして対象サーバ側には、~/rsyncd.confを以下のような感じで用意しておく。

use chroot = no

[MODULE_NAME]
path = /path/to/backup

use chroot = noは非rootだと必須。pathで指定した先を、MODULE_NAMEの名前でバックアップできるという形。

デフォルトでリードオンリなので、対象サーバをデーモン化して、バックアップサーバからpullしてくる分にはこれだけでいい。

なおポート問題は、SSH経由でつなぐ場合はそもそも関係ないっぽい。

さらなる詳細は、man rsync, man rsyncd.confあたりに載っているが、とりあえずこれだけわかれば使えそう。

sshで複数の秘密鍵がある場合、クライアントからはどの秘密鍵が使われたかわからない

authorized_keysでの実行可能なコマンドの制限を試すため、すでにエージェント転送で接続できるサーバに、別の公開鍵を追加した。

その上で ssh -i ... で新しく追加した鍵で接続してみたのだが、コマンドの制限が効いていない。

-vvvとつけて詳細なログを吐かせても、ちゃんと-iで指定した秘密鍵を使っている……ように見える。

といった感じではまっていろいろ試行錯誤した結果、以下のことがわかった。

  • -vvvで出てくる秘密鍵のパスは、じっさいに使われている鍵とは限らない。
  • sshに指定した鍵だけ使わせるには、-o 'IdentitiesOnly yes'で行ける。

ということで、以下のようにすれば解決。

ssh -o 'IdentitiesOnly yes' -i /path/to/private_key ...

なお今回は接続先サーバのroot権限がなかったからクラアイント側から調査したが、権限があれば多分ログ見ればさすがにわかりそう。

今だとVimのNginxシンタックスはなにを使えばいいのか?

軽くググると複数個出てきて迷ったので、今後迷わないように。
結論から言うと3つ目のがいいんじゃないかな。


github.com

> NOTE: As of Dec. 2013, these scripts are maintained in the "contrib" directory of the Nginx source:

公式的な扱いで、Nginx本体のcontribに入った?
が、今はメンテされてない?


github.com

> These files can be found under the folder contrib/vim. This repo is just here for convenient to be used with Vundle or Pathogen.

contribに入ったのベースで、Vundleやらから扱いやすくしただけ?


github.com

> The plugin is based on the recent vim-plugin distributed with nginx-1.12.0 and additionally features the following syntax improvements:

contribのものベースで、修正がされてるっぽい。ということで、今使うならこれかな?


なおどれもftdetectがファイル名 or ディレクトリ名を見るだけで、非rootユーザであちこちのディレクトリにある設定ファイルでNginx立ててる俺にはちょっと不便だったので、autoftでこんな感じの雑な設定して緩和してる。

let g:autoft_config = [
            \ { 'filetype': 'nginx', 'pattern': '\v%(charset_map|%(fastcgi|scgi|uwsgi)_param|(events|http|server|types)\s+\{|(upstream)\w+\{)' }
            \ ]

Microsoftの翻訳APIの使い方

なんか古い情報しか転がってなくて混乱したのでまとめておく。と思ったんだけど、ぜんぶ終わってから見つけたんだけど、 に現時点で最新と思われる情報が詳しく載ってるので、そっち参照した方がいいかも。

以下手順。

  1. 最近Azureの一部になってしまったので、Azure portalから入る。
  2. Azureの登録がまだならする。
  3. Cognitive Servicesとかいうのの一部になってしまったので、まずそれを探す。
  4. 新規作成する。
    • Account nameとResource groupが謎だが、とりあえず後者は後で変更できる。Account nameは不明だが、「アカウント名」とは違う気がする。
  5. KEY 1を安全なところに保存しておく。
  6. http://docs.microsofttranslator.com/oauth-token.html を見て認証部分のコードを書く。
    • にはKEY 1をそのまま書く。
    • キーをヘッダに書くパターンと、クエリに書くパターンがある。どちらでもいいが、PerlWebService::Simpleを使う場合はクエリつきのPOSTできないっぽいので前者で。
  7. http://docs.microsofttranslator.com/text-translate.html を見て翻訳部分のコードを書く。
    • ここでびっくり。このドキュメントにはエンドポイントのURLが書いていない! そして、認証の方のURLとは違う……。ここで引っかかった。
    • じつは機能の説明のフォームコントロール埋めて"Try it out!"ボタン押せば、実行結果が出てきてそこからエンドポイントが抜ける。

Azureに統合されたのが最近だってのもあってどうもあちこち混乱していて使いづらいが、API自体は必須パラメータ少なかったりして手軽だし、無料である程度使えるっぽいので試してみると楽しいかも。

YAPC::Kansai 2017に行ってきたのでトークの感想など

YAPC::Kansai 2017に行ってきました。去年のPHPカンファレンス大阪に続いて、カンファレンス2回目。今回は初懇親会も。

とりあえず駅までのバス、停留所逆側で待ってて、一本逃がして開場前に余裕で着く予定がぎりぎりに。

さらに、新大阪で下りてからだいぶ迷う。なぜか大阪駅だと思い込んでいたのだった。大阪駅ならまあ駅から出るくらいはなんとかなるだろうと、せっかく公式ブログで会場への行き方とか丁寧に説明されているのに読んでいなかった。そもそも大阪駅から出られるってのも怪しいんだが……。

まあでもなんとかオープニング中に入り込めたのでよかった。朝イチでかなり見たいトークがあってな。

10:20 ~ 10:40 メールフォームからメールを送る近代的な方法 | YAPC::Kansai 2017 OSAKA

最近HTTP APIでメール送る系にちょっと興味があったので。思ったより「近代的」な方の比重は小さかった。まあ時間の問題もあったみたいだが。

SMTPsendmailの割と基本的な話から入った。基本的とはいっても自分はそんなに詳しいわけじゃないので、あれこれ新しい知見も。

HTTP APIでの送信の方では、APIと同時にSMTPインターフェイスもあったりするというのがまったく知らなくて、興味深かった。

ある程度規模の大きなメール送信するならHTTP API試したいなあという気持ちが強まった。今のところsendmail経由で問題になるような規模でやることないんだが……。

あとバウンスメール処理のモジュールがあるようでこれがちょっと気になってる。

これだね。 Sisimai | bounceHammerの後継となるバウンスメール解析ライブラリ | Sisimai: Mail Analyzing Interface

10:50 ~ 11:10 オープンデータを利用したWebアプリ開発

トークはちょっと方向性が不明瞭だったが、オープンデータには興味が湧いた。国勢調査ベースのデータなんかが公開されてるらしくて、それけっこう使えるんじゃね? と。

PostGISGoogle Maps APIであれこれするのも楽しそう。

オープンデータあまり流行ってる感じじゃないので、今後流行るといいなあ。

11:20 ~ 11:40 高速化の初歩

基礎的な話。そこまで効果的ではないあたりから始めて、けっきょくいいアルゴリズムが大事だったり~みたいな流れ。ちゃんと無駄な高速化への戒めもあってよくまとまっていた。

11:40 ~ 12:00 Vue.jsで作るSPAから学ぶMVVM、非同期処理、その光と影

個人的に今回いちばん楽しかった話。事前にはそんなに期待してなかったんだけど。Vue.jsあまり関係なく、SPAもそこまで関係なく、MVVMとかPDSに関してのとてもわかりやすい話だった。

MVVMとかはかなり気になるネタだったので、ちょっとわかった気になれてよかった。わかった気になるだけじゃなくてちゃんとわからないとな……。

この辺いい本ないのかねー。

ベストトークに応募したのはこれ。

12:10 ~ 12:50 レガシーな Perl システムに DDD (ドメイン駆動設計)を取り入れる

これも事前から期待していた話。DDDまでは行かず、割と基本的なオブジェクト指向の話という感じだった。

「Serviceは状態を持つべきか否か」のあたりが興味深かった。状態を持つというか、staticメソッドだけのクラスじゃなくてコンストラクタでオブジェクト突っ込んでも、イミュータブルであれば別にいいと思う。

ただこの場合、Service側自体が不変でも、突っ込んだオブジェクトの方が可変になったりでややこしい気もする。

この辺はCQRSとかでなんとかするべきところなのかなあ。難しい。

13:40 ~ 14:00 コミュニティを開発していた元RubyエンジニアがPerlでゲーム開発を始めて感じたこと

この時間帯、B会場でやるトークも面白そうで迷ったんだけど、続く2トークがC会場だしとこっちに決め。楽しい話だった。

今時なかなかほかの言語からPerlに移ってくるような人っていない感じだし、こういう話はなかなか貴重。

14:00 ~ 14:20 Perl to Go

Perlで書かれた割とローレベルなことをやっているモジュールをGoに移植した話とかそんな感じ。

PerlはforkやりやすいがGoではそうではないらしいとか、PerlでハッシュでやっているものはGoでそのまま対応するデータ型でやるんじゃなくて、structにしてしまった方がいいとかそんな感じだったかな。

内容はもちろん、話し方も勢いがあって楽しかった。

14:20 ~ 14:40 なぜからはじめる開発

これも割と聞きたかった話なんだけど、時間配分甘かったのかいまいち頭に残らなかった。

あとこの辺から座りっぱなしのせいでつかれてきた。去年のPHPカンファレンスのときはこんなことなかったはずなんだが。YAPCの方がちょっとトークの密度高いかな?

14:50 ~ 15:50 GUEST: スペシャルセッション

リファクタリングの話……になったようなならなかったような。機材トラブルも含めて笑えるトークではあった。

16:00 ~ 16:20 Perl ウェブ開発の中世 〜CGIPlack の間〜

今回いちばん期待していたトーク。スライドも高品質で楽しい話が進んでいくが、残念ながら時間のせいで後半早送り気味。

後で懇親会をお聞きしたところ、話の中心をどこにするかで迷っていたとのことだったので、元々スライドの枚数も多めだったのかも。

でもこれは40分で聞きたかった。

PSGIは低機能なCGIに寄せたのがすごい」というのはまったく考えたこともなくて、はっとさせられた。

16:20 ~ 17:00 はてなシステムの考古学

はてなでの技術の変遷の話。夕方に見るにはちょうどいいゆるめのトークだった。

17:10 ~ 17:40 Lightning Talks

この辺もうだいぶつかれてきていて(座ってただけなのにな)、記憶も曖昧。ただ最初と最後の人の勢いがすごかったり、全体的に話しのうまさではトークの方より平均値上なんじゃねーのとか思ったのは覚えてる。

17:45 ~ 18:50 Keynote

割とだらだらといろいろなお話をされていた。尺長いしね。未踏の話とか、バイナリの話とか、Shibuya.pmの話とか。

19:30 ~ 懇親会

カンファレンスは二回目だが、懇親会は初めて。お店までちょっと迷ったが、今度は遅刻はせずに済んだ。

知り合いとかいるわけじゃないのでどんなもんかなーと思ってたが、一応何人かの方とお話できてとても楽しかった。

それほど広くない店の中に100人近いんじゃないかってくらい詰まってたが、これくらいの密度だったからこそ話せたのかも。

電車の時間の関係で途中で抜けなきゃならなかったのは残念だったけどなかなか楽しかった。

今後

今回LT応募したけど不採択だったのが心残りなので、その辺もっと頑張っていきたいなあとか。

そのためにはとにかく、話のネタになるようなことやってかなきゃだよね。

Gitの導入はなぜ失敗したか、どうすれば成功したか

YAPC::Kansai 2017のLTに応募してたんだけど不採択になったのでブログ記事にする。落ちるだけあって、大した内容ではないです ;-)

あとこの話はフィクションです。一応ね。

経緯

去年一年くらい、地方の中小企業的な某社(以後B社とする)に雇われて働いていた。PHPで、既存システムのリファクタリングとか、機能追加とかをやった。なおすべてリモートワーク。

B社はIT関係ではなく、自社システムのために社内にプログラマが多少いる、みたいな環境。半分内製、半分外注みたいな感じ。

B社のソフトウェア開発体制は、 ジョエル・テスト で0点取りそうな感じでまあ微妙。

VCS使ってないし、デプロイは自動じゃないし、バグ管理もスケジュール管理もできてないし、仕様書もない。

でも現状がいいとは思ってないみたいで、打ち合わせのときにも改善点ないか聞かれて、どうにかしようという意識はあるようだった。

ので、なにより自分のためにGitその他いろいろ提案したのだが……。

ツールは導入されました。しかしワークフローは改善されませんでした、みたいなことになった。

B社の開発ワークフローでつらかったのが、

  1. ソースコードのマスタが本番サーバにあるファイル。
  2. 作業がコンフリクトしないように、作業前に作業箇所を報告。
  3. 毎回本番サーバからダウンロードして、変更があれば手もとにマージ。手もとでは当然Git使ってるので。
  4. デプロイ前にもう一回ダウンロードしてきて、マージするなり。
  5. デプロイはFTPで手動。なお日付つきバックアップをしてからアップする。

みたいなあたり。

Gitを導入して、Gitリポジトリがマスタになれば、ほとんどの問題は解決するはずだった。

が、じっさいにはいろいろ問題が出て、なに一つ解決しなかった。

  • リポジトリの単位がおかしくて、一つのシステムが複数に分割されたりしていた。
  • ブランチが使われなかった。
  • コミットの粒度もおかしかった。

とかまあどうしようもない感じで、Gitリポジトリがマスタになれば、自動デプロイもすぐだなー、とか甘く考えてたのがぜんぶ駄目になった。

最初はこう思った

とにかく、もっとちゃんと使ってくれよ、わからないなら自分で学ぶか、せめて俺に聞けよ、と。

けどまあ、開発体制の改善が俺の仕事ではなかったし、リモートワークなんでコミュニケーションも取りづらいし、けっきょく行動しないままに仕事は終了。

終わってから今更ながら反省すると

落ち着いて考えると、目に見えるモチベーションなしに勉強なんてしないよね普通。そして、日付つきバックアップ作っていたような環境でいきなりGit使っても、便利さ感じるまで遠過ぎるよね、と。

じゃあ目に見える便利さがあればよかったんじゃないかな、便利さ駆動でなら学んだんじゃないかな、という結論に。

で、どうすれば便利だったか。いろいろ考えてみたけど、リモートで密なコミュニケーション取れるわけでもなく、立場的にあれこれ強制するわけにも行かず、みたいな前提だと、ワークフローを与えるみたいなのは却下。

じっさい、Gitやほかにもツール類はいくつか導入されたが、ワークフローの変更が必要な提案はどれも通らなかったし。

  • ツールの形で、
  • 一目瞭然な便利さがあって、
  • その便利さを継続して受けるためにGitをきっちり使う必要がある。

みたいなのが欲しい。

最終的には、Git + Jenkins + lftp使った自動デプロイスクリプトあたりで、とにかくワンタッチでデプロイできる形にした仕組みを丸ごと提案。

とかすればよかったんじゃないかなあと。

次機会があったら今回の反省を踏まえて、もっとうまくやりたいですね。

Redmineで細かなバグの扱いで悩んだけど、使い方の改善だけでなんとかなりそう

1つあたり平均5分もあれば直せそうな細かなバグが数十個とか報告されて、Redmine上での扱いをどうしようか悩んだ。

Redmineの使い方は割と普通。デフォルトからあまりいじっていない。プラグインも入れていない。ちょっと変わっているのが、自分一人で使っているということくらいだけど、ま今回はあまり関係ない。

RedmineとGitの連携はしていないが、チケット単位でブランチを切っている。また、作業時間のログを別途取っているのだが、それもチケット単位で、かつ30分単位でやっている。

という感じの前提。

まず思ったのが、こんな報告一つにつきチケット一つなんて面倒臭えよ、ってこと。

ただ、なんとなく面倒臭えよと思ってるだけじゃ駄目なので、具体的になにを面倒臭いと感じているのか、考えてみた。考えたというよりただ思い付いたことをメモっただけか。

  • 細かなバグがたくさんある。
  • いちいちチケットにするの面倒。
  • ぜんぶチケットにしたら、わざわざブランチ切ったり、作業時間のログ切り替えたりするの面倒。
  • ぜんぶチケットにしても、同じ原因のバグとかどうするの。
  • Redmineのチケット一覧性いまいちなんでまとめた後に内容を確認するのが面倒。
  • Redmineのチケット、テンプレートとかなくて不定形になるのでそこも面倒。

こうして羅列したものを一つずつ、どうすればいいか考えていった。

  • 細かなバグがたくさんあるのは、面倒だけど仕方ない。
  • ブランチや作業時間のログとの不一致は俺の作業方法の問題。ただこれは、Redmineの親チケット機能でまとめればなんとかなりそう。
  • 同じ原因のバグは、後から重複チケットとしてまとめればいい。
  • チケット切ること自体の面倒さと、テンプレートがない件は、URLクエリでデフォルト値を突っ込む方法 http://atotto.hatenadiary.jp/entry/2013/08/27/212556 で緩和できそう。
  • 一覧性の問題は、カスタムクエリで頑張れ、かな。今回知ったが一応チケットの本文も一覧に出すことはできるっぽい。

ということで、ほとんどの問題は解決するか、完全にはしなくても緩和できそうだった。


特にオチもないのだが、つらいと思ったときに思っただけで終わってちゃ駄目だよね、という話。