ファイル操作のテストなどで、特定の大きさのファイルを作成したいときがあります。そんなときは、 dd コマンドを使うと簡単に作ることができます。
dd if=/dev/zero of=test_file bs=1M count=10
上記の例だと、カレントディレクトリに「test_file」という10MBのファイルが生成されます。便利。
ファイル操作のテストなどで、特定の大きさのファイルを作成したいときがあります。そんなときは、 dd コマンドを使うと簡単に作ることができます。
dd if=/dev/zero of=test_file bs=1M count=10
上記の例だと、カレントディレクトリに「test_file」という10MBのファイルが生成されます。便利。
転職を機に perl を書くようになって以来、vim 一本で開発のすべてを行っています。
かつては、何と java を vi で書いていたこともあったし、運用でしばしば vi を使う機会があったので、基本的な操作は身に付いていたんですが、本格的に vi を使うようになって色々と便利な技があることを知ったのでシェアメモ。
まずは、文字コード変換。
:e ++enc=shift_jis :e ++enc=iso-2022-jp :e ++enc=euc_jp
これができないと、そもそも vim 一本で開発することができないという話。テンプレ編集やメール系の開発するときに便利すぐる。
続いて画面分割
:sp
これで画面が上下に分割して編集できます。画面を切り替える場合は、Ctrl+w を2回。プログラムを書いていて、「あ、これって他はどうしてるんだっけ?」と思って一時的に参照したい場合に便利です。
現在カーソルのある画面を閉じる場合は、
:close
現在カーソルのある画面以外をすべて閉じて、通常モードに戻す場合は、
:only
diff のように行単位で違いを眺めながら編集したい場合は、
Ctrl+w → v
これで垂直分割になります。純粋に 2ファイルの diff を見るのならば、vimdiff で OK なんですが。
分割したそれぞれの画面で別のファイルを表示するには、その画面に切り替えて、
:e ファイル名
これで、新しいファイルの編集モードに入れます。
ファイルを開くという意味では、編集中のファイルにあるパスにカーソルを合わせて
gf
これで、そのパスにあるファイルを開くことができます。これ、ヤバイです。芋づる式にプログラムを編集できます。grep 結果をファイルにリダイレクトしておいて、あとで開いて順番に見ていきながら編集する場合に重宝しました。
画面分割は、「screen 使えば良いんじゃないの?」という話もありますが、ちょっとした比較には vim の画面分割はダントツに力を発揮します。特に、ノートPCやサーバのコンソールのように、小さい画面で頑張らないといけない時なんかは、知っていると知らないとでは作業効率に雲泥の差が出ますよ、ホントに。
ということで便利技をいくつか書いてきましたが、要するに「java × eclipse の開発は便利で良かったなぁ」ということです。 vim でどんなに頑張っても、さすがにアレにはかなわないですね。
ヒアドキュメントを使って、ファイルに内容を書き出そうと思ったんだけど、どこにリダイレクトを書くのか分からなくて苦戦した。ううう。
正解はこちら。最初に指定しておくのか。なるほど。
cat << HERE >> /tmp/hoge 2>&1 xxxxxx yyyyyy zzzzzz HERE
bashのヒアドキュメントは、メール送信以外で使ったのは、これが初めてかもしれない。便利な仕組みだけど、あんまり用途が思いつかない。
csvデータをpostgresqlにインポートしようとしたら、エラーが。
ERROR: invalid byte sequence for encoding "SJIS": 0x00
NULL文字が含まれているのが、納得いかないようす。NULL文字は目で見えない制御文字なので、どうやって削除したもんかなーと思ったら、trコマンドで簡単に除去できました。
$ cat src.csv | tr -d "\000" > dest.csv
これでインポートはバッチリでした。
マイナーな圧縮形式になるとコマンドを忘れがちなので、まとめのメモ。
まずは基本の gz 形式から。(さすがに忘れないけど)
圧縮 $ gzip filename 解凍 $ gunzip filename.gz
続いて、tar.gz (tgz) 形式。(これも忘れないなあ)
圧縮 $ tar cvfz dirname.tar.gz dirname 解凍 $ tar xvfz dirname.tar.gz
bzip2 (bz2) 形式。
圧縮 $ bzip2 filename 解凍 $ bzip2 -d filename.bz2
tar.bz2 形式。
圧縮 $ tar cvfj dirname.tar.bz2 dirname 解凍 $ tar xvfj dirname.tar.bz2
Windowsとのデータやり取りの基本、ZIP形式。
圧縮 $ zip filename.zip file1 file2 解凍 $ unzip filename.zip
これまたWindowsとデータ交換するとよく出てくるLZH形式。
圧縮 $ lha -a filename.lzh file1 file2 解凍 $ lha -e filename.lzh
こんなところでしょうか。個人的には、tar.bz2形式とLZH形式の解凍が、いつも一発でいきません。あうあう。どうもオプションが覚えられないんだよなあ。チートシート、チートシート、と。
年に1回くらい需要があることが分かったので、ここらへんでメモしてみる。
# useradd -s /sbin/nologin -M ftpuser # passwd ftpuser # mkdir -p /ftp/userdir # usermod -d /ftp/userdir ftpuser # chown ftpuser:ftpuser /ftp/userdir # chmod 705 /ftp/userdir
useradd で /sbin/nologin を指定することで、telnet などでログインできないユーザを作成できる。また、-M オプションを付けると、ホームディレクトリを作成せずにユーザを作成するので、不要なメールボックスが作成されないで済む。FTP先のディレクトリは、usermod で後から設定してあげればOK。
ざっくりこんな感じ。
ただ、qmail が動いていると、メールボックスは無いんだけれども、/etc/passwd にエントリされるだけで、有効なアカウントと判断してしまう。だもんで、例えば ftpuser 宛にメールをすると、ローカル配送してしまう。まあ、メールボックスが無くてエラーになるので、目的を達成してはいるんだけど、"no mailbox" なエラーじゃないので、いただけない。
ここらへん、厳密に対処するのであれば、qmail でメールアカウントだけを削除する方法のように、ごにょごにょしてやらないといけない。ちょっと大げさ。
色んなサービスが動いていると、細かいところで厄介になるなー。
SSLを設定してApacheを立ち上げようとすると、秘密鍵のパスフレーズを問合せてくる。
手動で運用している分には問題ないのだけれども、スクリプトで起動するような操作をする場合に面倒くさいことになる。そこで、パスフレーズの入力を回避してみる。
# openssl rsa -in server.key -out server.key.nopass
これで、元の秘密鍵からパスフレーズ抜きの鍵を生成して、これを SSLCertificateKeyFile に指定してあげれば、次回の起動からはパスフレーズの入力なしで、Apacheを起動できます。わーい、便利。
ただし当然ながら、これはセキュリティ上、好ましくないので、単純に「めんどくせえなあ」ということなら、やめておいた方が良いと思います。そういう意味では、裏技ですね。
ちなみに、
# apachectl startssl
として起動しようとしたら、怒られてしまった。
Apache2.2からは、startssl などと書かずに、普通に start や graceful でSSL起動ができるようになったとのこと。ほう、こりゃまた便利な世の中ですなあ。
ということで、
# apachectl start
のコマンド一発で、パスフレーズ入力もなく、SSLを意識せずにApacheの運用が出来るようになりました。お疲れさまでした。
新規にドメインを取得し、自分でネームサーバを立てて運用をしようとするも、うまくいかずに数日ほどハマる。
ゾーンファイルを書き換えたりすることは日常的に行っており、DNSの仕組みも把握していたので、ゼロから構築するのもイージーだろうと思っていたら、まあ、色んなミスを重ねてハマりまくった。反省の意味も込めて、メモ書き。
1台のサーバで複数ドメインの SSL 対応をやることになって、サーバ(というかNIC)に複数のIPアドレスを割り当てることになった。名前ベースの VirtualHost だと SSL 対応できないからね。VirtualHost で複数 SSL 運用するのであれば、IPベースしかないわけです。
こういう場合は、IPエイリアスを使うのが定石。
# ifconfig eth1:0 xxx.xxx.xxx.11 netmask 255.255.255.240 # ifconfig eth1:1 xxx.xxx.xxx.12 netmask 255.255.255.240
こんな感じで、NIC(ここではeth1)に複数IPアドレスを割り当てていけば OK なんだけど、このままだと、再起動時に設定が無効になっちゃう。仕方なく network の起動スクリプトに、同じコマンドを記述して起動していたんだけど、Redhat なら静的ファイルで管理できるみたい。
# cat /etc/sysconfig/network-scripts/ifcfg-eth1 DEVICE=eth1 BOOTPROTO=static BROADCAST=xxx.xxx.xxx.15 HWADDR=xx:xx:xx:xx:xx:xx IPADDR=xxx.xxx.xxx.10 NETMASK=255.255.255.240 NETWORK=xxx.xxx.xxx.1 ONBOOT=yes TYPE=Ethernet
という NIC に対して、次のようにエイリアスファイルを作っていけば OK みたい。
# vi /etc/sysconfig/network-scripts/ifcfg-eth1:0 DEVICE=eth1:0 BOOTPROTO=static BROADCAST=xxx.xxx.xxx.15 HWADDR=xx:xx:xx:xx:xx:xx IPADDR=xxx.xxx.xxx.11 NETMASK=255.255.255.240 NETWORK=xxx.xxx.xxx.1 ONBOOT=yes TYPE=Ethernet
# vi /etc/sysconfig/network-scripts/ifcfg-eth1:1 DEVICE=eth1:1 BOOTPROTO=static BROADCAST=xxx.xxx.xxx.15 HWADDR=xx:xx:xx:xx:xx:xx IPADDR=xxx.xxx.xxx.12 NETMASK=255.255.255.240 NETWORK=xxx.xxx.xxx.1 ONBOOT=yes TYPE=Ethernet
これまで1枚の NIC に対して 1つのファイルなんだと思っていたので、エイリアスの場合どうするのかなーなんて思っていたんですが、IPエイリアスごとにファイルを用意して管理できるんですねー。これは良いこと知りました。ありがとうございます。
Apache2.2系では、Tomcatと連携するのに、mod_jk を入れずとも mod_proxy_ajp モジュールを使って対応できるようなので、試してみた。
mod_proxy.so と mod_proxy_ajp.so が必要になるので、次のようにコンパイルする。とりあえず、他にも色々と必要だったりしたので、次のようにした。
# tar xvfz httpd-2.2.8.tar.gz # cd httpd-2.2.8/ # ./configure --prefix=/usr/local/apache \ --enable-so \ --enable-shared \ --enable-rewrite \ --enable-ssl=shared \ --with-mpm=worker \ --enable-deflate \ --enable-headers \ --enable-dav=no \ --enable-proxy-ajp \ --enable-proxy \ --enable-mods-shared=all # make # make install
Tomcat 側のデフォルトのAJPポートは 8009 なので、変更なければ、httpd.conf に次のように書けば終わり。
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
<Location /manager/> ProxyPass ajp://xxx.xxx.xxx.xxx:8009/manager/ </Location>
これで、それまで http://xxx.xxx.xxx.xxx:8080/manager とアクセスしていたところ、http://xxx.xxx.xxx.xxx/manager とアクセスできるようになる、と。mod_jk に比べてすんごくラクチン。これは良いかも。
PAM (Pluggable Authentication Modules)認証で、pam_ldap.so モジュールを使用するとき、LDAPに接続できないと、長いこと待たされる。LDAP側で管理しているユーザではなく、shadowファイルなどで認証チェックがOKとなっても、2分くらい待たされる。なんでじゃ。
PAMのsystem-authはこんな感じ。
#%PAM-1.0 auth required /lib/security/pam_env.so auth sufficient /lib/security/pam_unix.so likeauth nullok auth sufficient /lib/security/pam_ldap.so use_first_pass auth required /lib/security/pam_deny.so
account required /lib/security/pam_unix.so broken_shadow account [default=bad success=ok user_unknown=ignore service_err=ignore system_err=ignore authinfo_unavail=ignore] /lib/security/pam_ldap.so account required /lib/security/pam_permit.so
password required /lib/security/pam_cracklib.so retry=3 type= password sufficient /lib/security/pam_unix.so nullok use_authtok md5 shadow password sufficient /lib/security/pam_ldap.so use_authtok password required /lib/security/pam_deny.so
session required /lib/security/pam_limits.so session required /lib/security/pam_unix.so session optional /lib/security/pam_ldap.so
ついでに、nsswitch.confも。
passwd: files ldap shadow: files ldap group: files ldap
まあ、よくある基本的なLDAP認証の設定です。これで、LDAPに登録したアカウントでの認証もできるし、無論LDAPに登録していない元からのアカウントでの認証もできる。つまり、LDAPが落ちていても、shadowファイルとかに情報があれば、認証をパスできるわけです。
ところが、実際にLDAPを落として、SSHでログインを試みると、ログイン認証ごときに尋常じゃなく待たされる。ログ(/var/log/secure)を見てみたら、こんなことに!
sshd[29791]: Accepted password for plab from xxx port 3496 ssh2 sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 4 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 8 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 16 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 32 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: reconnecting to LDAP server (sleeping 64 seconds)... sshd[29793]: nss_ldap: failed to bind to LDAP server ldap://xxx: Can't contact LDAP server sshd[29793]: nss_ldap: could not search LDAP server - Server is unavailable
どうやら認証処理うんぬんではなく、LDAPサーバに接続できるまで、時間を置きながら最大5回までチャレンジしているため、時間がかかりまくっているみたい。何らかの原因でLDAPサービスが落ちたとき、復旧でSSH接続しようとしたら2分かかりました、ってのはキツイ。もうちょっと空気読もうよ、nss_ldapさんっ!
実際、LDAPサービスの死活を判断するのに、トータル124秒も待って5回も再接続を試みる必要があるケースは少ないと思う。同じネットワークエリア内にドメインコントローラを置いたりするなら、これは大げさすぎるんじゃないか、と。
ということで、nss_ldapの再試行回数やタイムアウト時間を変更する方法。
Apacheはroot権限で起動したあと、セキュリティ確保のため、子プロセスを一般ユーザー(nobodyとか)で生成する。今日は、この子プロセスも、rootで起動しちゃおうという話。
CGIは通常、子プロセスの一般ユーザー権限で実行される。そのため、より高い権限が必要なファイル操作を行おうとすると、パーミッションエラーになったりする。この手の問題には、suexecで対処するのがセオリーだけど、「そもそも実行ユーザーをrootにしちゃえば、何でもできるんじゃないの?」というコペルニクス的転回があって、試してみたら、できちゃった。おおっ!
以下、その方法。
DreamWeaverで構築したサイトのソースが汚いので、5分くらいでクリーンアップするshを書いてみた。あとで汎用性あるように、改造するために、ここにメモ。
#!/bin/sh
echo 'remove Templates directory' rm -Rf Templates/
for FILE in `find . -name '*.html' -print` do echo ${FILE} while true do COUNT=`grep '<!-- Instance' ${FILE} | wc -l` if [ ${COUNT} -eq 0 ]; then break; fi perl -pe 's/<!-- Instance.*? -->//' ${FILE} > ${FILE}.$$ mv ${FILE}.$$ ${FILE} done done
exit
DreamWeaver自体にもソースのクリーンアップとか機能があるらしいんだけど、テンプレートから切り離したりしなくちゃいけないんで、面倒らしい。そこらへんDreamWeaver使いじゃないので、よく分からない。正攻法を調べる時間もなかったので、全部サーバに上げてもらって、shスクリプトで処理した次第。
DreamWeaverぐらいのソフトになれば、これ以上のことを、コマンド一発でやれそうな気がするのだけど。知っている人いたら、教えてくださいまし。
時限的なサイトの運営でよくあるのが、閉鎖時に「サイトのどのページにアクセスされても、『サービス終了のお知らせ』ページを表示させたい」という要件。具体例を出すと、
http://www.hoge.com/aaa/index.html
http://www.hoge.com/ccc/ddd/index.php
こういったHTTPリクエストに対して、常に
http://www.hoge.com/close.html
を表示させるというもの。
様々な方法があるとは思うのだけれども、個人的に常用しているのは、Apacheのmod_rewriteを使った方法。なぜ常用しているかと言うと、Apache以外のWebサーバーを運用したことが無いから。
以下、その方法。
CGIへのアクセスをSSL通信にしたい。
ということで、真っ先に思い浮かんだのが、CGIへのリンク全てのURLを「https://~」というフルパスの記述に変える方法。でも、これだとSSL対応していないプラットフォームでの運用に支障が出るし、何より開発時と本番時で絶対パスを変えたりして、開発コストがかかりそう。
そんなわけで、apache側の設定でリダイレクトさせるのが一番かなと思って、やってみた。
<FilesMatch "\.cgi$">
RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^/usr/local/apache/htdocs/(.*)$ https://www.hoge.com/$1 [L]
</FilesMatch>
SSL通信(443ポート使用)でないCGIへのアクセスを、mod_rewriteを使って、httpsへリダイレクト。.phpとか.doとか、拡張子が増えたときでも、これなら簡単に追加できそう。LocationMatch ディレクティブとか使って、もっとキレイに実現する方法もありそうだけど、とりあえずは良しとしよう。
いまだにApacheの設定は、うまくいくまで手探り。なかなか1発で思うように動いてくれた試しがない。慣れの問題なのかもしれないけど、そんなにApacheをイジることはないからなあ。