mochikoAsTechのdig日記

当方好きなコマンドはdigです!お友達から!!よろしくお願いします!!!

「このファイルは絶対に消さないで」とお願いしておくより、chattr +i しておいた方が確実で安全

複数名でサイトを更新したり、rsyncで定期的にファイルが更新されるようなとき、「このファイルだけは!消したり、更新したりしないで!触らないでえええ」というファイルがあったら、一生懸命お願いするよりchattr +iしておく方が確実だし安全。

chattrコマンドはchange attribute(属性の変更)の略で、ファイルの属性を色々変更できる。

chattr +i ファイル名

しておけば、オプションのiはimmutable(変更不可)なので、これをやっておくと、ファイルに対して読み書き実行の権限を持ってるオーナーは勿論、なんとrootですら一切変更・削除が出来なくなる。rootがrm -fしたって、rm: cannot removeと出るから安心!

逆にchattrで設定してあることを知らずに、lsで権限を確認して、権限はあるはずなのにこのファイル消せないー!となった時は、lsattrコマンドで状態を確認すべき。

# lsattr ファイル名
----i--------e- ファイル名 ←iが付加されている状態

# chattr -i ファイル名 ←-オペレータで、i(変更不可)の属性を解除すると
# lsattr ファイル名 ←iが消えた
-------------e- ファイル名

-(マイナス)オペレータでiを解除してやれば、ファイルは触れるようになる。わー、chattr便利ー。

WordPressの更新をFTPからSSHの鍵認証に変更したい

WordPress本体の更新とか、プラグインやテーマの追加を管理画面からしたーい!でもFTPはいやじゃー!SSHでさせろー!と思ったら、色々ごにょごにょしなきゃダメだった、というメモ。

先ずは

yum install php-pear
yum install libssh2 libssh2-devel
pecl install ssh2

したら怒られたので、

yum install php-devel
pecl install channel://pecl.php.net/ssh2-0.12
vi /etc/php.d/ssh2.ini
extension=ssh2.so を追記
/etc/init.d/httpd restart

で管理画面開いたら、選択肢にSSH2が増えてた!

ここまでの参考: WordPressでFTP接続情報が表示、SSH転送で回避 | WordPress on LAMP(Linux、Apache、MySQL、PHP)でサーバー管理入門 phpでssh2を使えるようにpecl ssh2をインストールする | レンタルサーバー・自宅サーバー設定・構築のヒント うえちょこ@ぼろぐ» [php]PECLコマンドが成功するまでのエラー解決備忘録(imagick編) Editing wp-config.php « WordPress Codex

そしてここ見ると鍵ペア作って、公開鍵を自分のauthorized_keysに入れろって言ってるんだよね。ちょっと待て、お前WordPressが動いてるサーバで作った秘密鍵を、WordPressの本家サーバに持ってく気なのか?AWS方式か?え。え。>http://serverfault.com/questions/182508/wordpress-ssh-upgrade-problem

なんかそれ嫌だなー、と思いつつ、試してはみたところ、

Aug 27 13:39:11 galbo sshd[4732]: Set /proc/self/oom_score_adj to 0
Aug 27 13:39:11 galbo sshd[4732]: Connection from 153.121.58.159 port 50876
Aug 27 13:39:11 galbo sshd[4733]: Received disconnect from 153.121.58.159: 11: PECL/ssh2 (http://pecl.php.net/packages/ssh2)

SSHのログにこう出るばかりで、どうしても鍵認証が失敗して更新できない。

ので、今のところ更新が必要な時だけ、一時的にSSHのパスワード認証をオンにしてWordPressやらプラグインやらを更新してる。勿論、更新後はすぐにPasswordAuthentication = noにしてる。もうこれでいいか・・・なんか負けた気分だ・・・。

IfModuleディレクティブのあるなしの不思議

割と古めなApachehttpd.confだと、DirectoryIndexディレクティブの記述が

<IfModule dir_module>
DirectoryIndex index.html
</IfModule>

ってなってて、なんで「dir_moduleがあったら」なんだろー?と思ったら、万が一なかったときでも、Apache起動するようにという安全策なのだね。

最近はこのモジュール入ってないことなんかないから、最近yumで入れたApache 2.2.15のhttpd.confでは、普通に

DirectoryIndex index.html index.html.var

になってた。>http://httpd.apache.org/docs/2.2/ja/mod/mod_dir.html

そしてindex.htmlはともかく、その後ろのindex.html.varってなんぞ?と思ったら、HTTP/1.1のコンテントネゴシエーションなのね。ブラウザの言語によって、返すコンテンツを変えたりできるとな!>http://httpd.apache.org/docs/2.2/ja/content-negotiation.html

RewriteRule ^(.*)$ [F]って書いたのに、403 Forbiddenじゃなくて400 Bad Requestが返ってくるのはなぜ?

ある条件に当てはまるリクエストが来たら、403 Forbiddenを返したい!と思って、RewriteRuleを調べてたらこんなの出てきた。

mod_rewriteでアクセス拒否? | Life is Real.

「おおー、[F](=[forbidden])なんてあるんだー」と思ってこう書いた。

RewriteEngine On
RewriteCond 「こういう条件に当てはまったら」という条件文
RewriteRule ^(.*)$ [F]

そしたら何故かRewriteRule ^.*$ [F]でアクセスしたら、「400 Bad Request」になりまし... - Yahoo!知恵袋とまったく同じ状態になった。えー、403 Forbiddenじゃなくて400 Bad Requestが返ってくるのはなんでー?

と思ったら答えはやっぱりApache公式にあったよ。

mod_rewrite - Apache HTTP Server Version 2.2

403じゃなくて400が返ってきたのは何故か?何故ならば、書式ルール的には「RewriteRule Pattern Substitution [flags]」って書くべきなのに、真ん中のSubstitution(置換後の文字列) をすっ飛ばして「RewriteRule ^(.*)$ [F]」って書いてたからでした。Patternとflagsしかなかったんだね。

mod_rewrite - Apache HTTP Server Version 2.2にちゃんと

- (dash) A dash indicates that no substitution should be performed (the existing path is passed through untouched). This is used when a flag (see below) needs to be applied without changing the path.

と書いてあるので、「RewriteRule ^(.*)$ - [F]」が正解でした。チーン。(要は「置換とかしないならハイフン使え」と書いてある)

RewriteEngine On
RewriteCond 「こういう条件に当てはまったら」という条件文
RewriteRule ^(.*)$ - [F]

これならちゃんと403が返ってきたよー!わー!

ctrl+r(reverse-i-search)で進みすぎた時、1つ戻るにはctrl+s(i-search)だ!

ctrl+rのreverse-i-searchが好きだ!

何が良いって、うっかり他のサーバとか他のユーザでログインしてると、ctrl+rで期待する候補が出てこなくて「あれ?」ってなるのがいいよね。(例えばDNSサーバにログインしてるつもりで、「cd /var/named/chroot/var/named」を探してchroとか打っても、ウェブサーバだから結果出てこなくて、そこで「あれ?あ、サーバ間違えてた」って気づく)

でも1つだけ不満があった。

reverse-i-searchで次候補に行くにはctrl+rを押せばいい、けど前候補に戻るには?一旦ctrl+cで抜けてやり直すしかないのかな。「あ、行き過ぎた!いっこまえの!」って結構やるから戻れたら嬉しかったんだけど・・・と思ってたらあった!

通常、ctrl+sってうっかり押すと、画面がロック(正確にはターミナルへの出力が停止)されてあばばばばばってなってたんだけど、この「ctrl+sは画面ロックに割り当て」という設定を無効にしてやれば、ctrl+sがi-search(1つ戻る)になる模様。

先ずはsttyコマンドで現在の設定を確認。4行目に「start = ^Q; stop = ^S;」とあるのが、ctrl+sはストップ(画面ロック)でctrl+qがスタート(画面ロック解除)の意。

$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

という訳で、ホームディレクトリの.bashrcか、それか全ユーザに適用しちゃいたいなら/etc/bashrcに以下を書けばOK。

# 画面ロックの設定を解除してi-searchに割り当て
stty stop undef
stty start undef

ちなみにsttyはttyの設定を変更するコマンド。setting ttyってことか。んで、undefは「無効にする」ための値。

さらに補足するとTTYはteletypewriterの略で、マシンに直接繋がってるコンソールターミナル。ptsはpseudoterminal slaveの略で、こっちは外からSSHで繋いでる仮想(疑似)ターミナルのこと。あれ?じゃあsttyはttyの設定じゃなくてttyとptsの設定を変更するコマンドなのか・・・?まあ今はいいか!気にしない!

設定後にbash読み込み直して(=ログアウトして、ログインし直して)もう一度、stty -aしてやると、startとstopの値が<undef>になってるのが分かる。

$ stty -a
speed 38400 baud; rows 24; columns 80; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>;
eol2 = <undef>; swtch = <undef>; start = <undef>; stop = <undef>; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -cdtrdsr
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke

これでctrl+sで「1つ前に戻る」が出来るようになったー!私は勿論、/etc/bashrcにいきおいよく書いたよ!ctrl+rとctrl+sでまじはかどる。

でもサーバ1つ1つに設定するの面倒だなー、と思ってたら、これを設定してあるサーバからsshで別のサーバにログインしても何故か設定引き継がれてた!なにこれ!ttyの設定って引き継がれるの?その辺はまだ調べるけど、なにこれ嬉しい誤算・・・。

参考:Ctrl+rでコマンド実行履歴を検索して、通り過ぎてしまったときの対処法 | hello-world.jp.net

ps -aux叩いたらWarningが出た

$ ps -aux
Warning: bad syntax, perhaps a bogus '-'? See /usr/share/doc/procps-3.2.8/FAQ

というように、ps -aux叩いたらシンタックスの誤りを指摘されたので、言われた通り /usr/share/doc/procps-3.2.8/FAQ を見てみたら、まんま「なんでps -aux叩くと、ハイフンについて文句言われるのか?」が書いてあった。

Why does "ps -aux" complain about a bogus '-'?

According to the POSIX and UNIX standards, the above command asks to display
all processes with a TTY (generally the commands users are running) plus all
processes owned by a user named "x". If that user doesn't exist, then ps will
assume you really meant "ps aux". The warning is given to gently break you of a
habit that will cause you trouble if a user named "x" were created.

要約すると「お前が実行したいのはps auxだと思うけど、ps -auxだと本当は出力結果違うから、次からはハイフンなしを使えよ」と注意されてる模様。

「ps aux」だとuが「ユーザー指向のフォーマットでプロセスを」、axが「全て表示」なんだけど、

「ps -aux」だと、-uxが「このユーザ(x)のプロセスを」、-a が「全て表示」になって、xのプロセスが出ちゃうのか。

ハイフンありとなしで全然違うオプションなんだね、その辺はman psしたら詳しく書いてあった。

たまたま「x」という名前のユーザが居なければ、「ps -aux」でも「ps aux」と同じ結果が得られるけど、それはpsコマンドの親切心から来るもので、いずれは変更される可能性もあるし、そもそもxというユーザが作られたらそこで終わりなので、早めにハイフンなしを使うことに慣れとけよ、という忠告なんだね。ありがとう、psコマンド。

rootだけvimじゃなくてvi使わされてるのなんで?

ここからここまでぜーんぶ先頭に「//」を入れてコメントアウトしたーい!みたいなときに、vimの短形ビジュアルモード便利!と思ったけど、viじゃ使えないのか・・・vim限定なのか・・・・つーかもうシンボリックリンクになってて、この2つ完全に同じだと思ってた・・・ということがあったのでメモっておく。

一般ユーザとrootユーザでviの中身は違う

そもそも私の中の理解は「viがもっと改良されたのがvim。でも最近はviって打っても、実体としてはvim使ってるので、両方同じものだと思ってよい」くらいだった。

なんだけど、viとvimでなんか挙動違う!と思ったら、一般ユーザとrootユーザで、viの中身が違うんだね。

こっちが一般ユーザで「viのフルパス教えろよー」としたとき。「viはvimエイリアス(別名)だよ、フルパスは/usr/bin/vimだよ」って返事が返ってきてる。

$ which vi
alias vi='vim'
/usr/bin/vim

そしてこっちがrootユーザで同じこと聞いたとき。「viのフルパスは/bin/viだよ」って返ってきてる。

# which vi
/bin/vi

えー、なんでrootは生のままのvi使わされてるの・・・?

なぜrootだけ生のままのviを使わされているのか?

色々調べて行ったら、/etc/profile.d/vim.shでわざわざUIDが200以上のユーザだけに限定して「alias vi=vim」してて、そのvim.shを/etc/bashrcの中で読み込んでる。(つまりrootユーザのUIDは0なので、viにエイリアスが設定されない)

if [ -n "$BASH_VERSION" -o -n "$KSH_VERSION" -o -n "$ZSH_VERSION" ]; then
  [ -x /usr/bin/id ] || return
  ID=`/usr/bin/id -u`
  [ -n "$ID" -a "$ID" -le 200 ] && return
  # for bash and zsh, only if no alias is already set
  alias vi >/dev/null 2>&1 || alias vi=vim
fi

えー、なんでー、なんでrootユーザはvim使えないの・・・vim-enhancedパッケージのあるなしとか関係あるの?

別に自分で/root/.bashrhで「alias vi='vim'」とかしてもいいんだけど、わざわざこうしてある理由が分からないまま、設定しちゃうのも嫌だしなー。