Debian jessie + さくらのVPSでLet’s Encryptを使う

どうやら最近SSL対応のサイトが増えているようで、「暗号化する必要あるんだろうか?」というどうでもいいサイトまでhttpにアクセスするとhttpsにリダイレクトされたりもします。
そうなってくると大手サイトがhttpを使っていると、まだSSL入れてなかったんかいなどと思ったりもします。

スマホもパソコンも速くなった今、全ての通信が暗号化されるのはいいことだと考えております。
かといって個人が証明書にお金払うのは微妙ですし(僕は前払ってましたけどもすごく微妙な気持ちになりました)、オレオレ証明書使うのは更に微妙です。

team2ch.orgもなんとなくSSLを入れてみたくなったので、2016年くらいから話題の「Let’s Encrypt」を使って無料で認証局から証明書を発行してもらいました。
それをApache2で使えるようにするまでの手順を書きます。

続きを読む

ネットワークカードを交換したらeth0が使えなくなった時の対処法(Debian, Ubuntu)

Ubuntu 14.04とDebianの古いシステム(squeeze)のネットワークカードを変えたらeth0が上がってこなくなりました。
Intel純正のPCI-Eアダプタ(Intel GIGABIT CT DESKTOP ADAPTER)、オンボードのLAN(これもPCI-E接続のIntelチップ)共に上がってこないという状況でした。

つまり状況としては両OSとも

    lspci | grep Intel → PCI-Eアダプタ、オンボードのLAN共に認識されている
    lsmod | grep e1000e → loadされている
    /etc/network/interfaces → 特に問題なし

    ifconfig → loは出てくるがeth0が出てこない

という感じでした。

ググってみたら、MACアドレスとethxの対象関係は

    /etc/udev/rules.d/70-persistent-net.rules

に記述されていると分かりました。

なので、アナログな方法でネットワークカードのMACアドレスを調べて、NAME=”eth0″を付けるカードを指定し直すことで問題解決しました。
分かれば簡単でしたが、半日ほどハマりました。

参考URL:Ubuntuでネットワークカードを変更した時

Debianのブートディスクを交換

ルーター機のブートドライブを300GのHDDから32GBのSSDに交換しました。
逆の場合であれば# dd で一発なのですが、ディスク容量が小さい方への移行なのでそうはいきません。なので地道にやってみました。OSはルータがDebian、母艦がUbuntuです。最悪、起動しなくても最初のほうでバックアップを取ってるので復旧は容易かと思われます。

・ファイルシステムのバックアップ
旧HDDを母艦に接続して丸ごとcp -R するだけです。

# 旧HDDのUUID (gpartedかなにかで調べられます)
HDD_UUID=732cf650-8bc9-44b0-b2fd-9aa1a7743f60

sudo cp -R /mount/${HDD_UUID} .

・新SSDのフォーマット
gpartedかなにかでやると楽です

・新SSDへファイルをコピー

# 新SSDのUUID (gpartedかなにかで調べられます)
SSD_UUID=3fe19005-d2cb-4dd7-ae79-858ca95de327

cd ./${HDD_UUID}
sudo cp -R . /media/${SSD_UUID}

・ブート領域を作ってあげる
僕が前に書いた記事GRUBを飛ばしてしまいシステムが起動しなくなったときの救出方法と同様のことをやります(再掲)
詳しくは元リンクを参考にしてください。

# /boot パーティションのUUID./ 上に/boot がある(救出先のシステムで/boot を切り分けてない)なら省略
BOOT_UUID=0e0670da-9711-4eab-8025-b26dba90d576

# 救出先システム上/ のUUID
SYS_UUID=21427729-aef2-4a52-8d28-d6e90804c659

sudo mount --bind /proc /media/${SYS_UUID}/proc
sudo mount --bind /sys /media/${SYS_UUID}/sys
sudo mount --bind /dev /media/${SYS_UUID}/dev
# / 上に/boot がある(救出先のシステムで/boot を切り分けてない)なら省略
sudo mount --bind /media/${BOOT_UUID} /media/${SYS_UUID}/boot

sudo chroot /media/${SYS_UUID}
# たとえば/dev/sdeに grub をインストールしたい時
grub-install /dev/sde
update-grub
exit

sudo umount /media/${SYS_UUID}/proc
sudo umount /media/${SYS_UUID}/sys
sudo umount /media/${SYS_UUID}/dev
# / 上に/boot がある(救出先のシステムで/boot を切り分けてない)なら省略
sudo umount /media/${SYS_UUID}/boot

・HOMEディレクトリのownerを元に戻す
HOMEの所有者を旧HDDシステムで使っていたユーザ名に戻してやります。やらないと、SSHが通らなかったり何かと不便です。


cd /media/${SSD_UUID}/home
sudo chown -R user:user ./user

・suが通るようにする
これもパーミッション設定なのですが、あまり見慣れない形式です。詳しくはsudo で 「sudo: must be setuid root」と怒られる – 不会忘記的一天に書いてあるとおりです

# chmod 4511 /usr/bin/sudo

・繋ぐ
SSDを繋いで起動することを確認。以上。

参考リンク
sudo で 「sudo: must be setuid root」と怒られる – 不会忘記的一天

Debian lennyからsqueezeにdist-upgrade

ルータ機をlenny からsqueeze にdist-upgrade しました.
SSH 経由でちゃちゃっとやりましたが上手くいきました.X は使っていないし使う予定もないので気楽でした.

自作のスクリプトやbind の設定ファイルをバックアップした後,

$ su
# apt-get update
# apt-get upgrade

# nano /etc/apt/sources.list

lenny を squeeze に変更.つまり,

sed -e s/lenny/squeeze/

squeeze からは debian-volatileが廃止されるようです.ついでに/etc/apt/sources.list から外しておきましょう.

# apt-get update
# apt-get upgrade
# apt-get dist-upgrade
# reboot

デフォルトのシェル(つまり/bin/sh)をdashにするか?という主旨のことをdist-upgrade 中に聞かれました.
よく分からないのでググったら,こういうことらしいです.

MEMO:はてな支店 [shell]dash

僕はbash に慣れきっているので(←もちろん賛否両論あることは知っています),「No」を選択しました.

アップグレード後,NATが上手く動作しなくなってしまったのですが,ルータの/etc/network/interfaces を見たり,クライアントのネットワークを再起動したりしていたら繋がるようになりました.

メイン機(Ubuntu 10.10 Maverick)とHTTPサーバ(Debian lenny)は,動いているアプリケーションがあまりにも多く,躓く可能性が高いので様子見にしました.そのうちやります.

参考URL
cpn blog vmware で Debian lenny から squeeze へアップグレード
Debian 6.0 Squeeze アップグレード

出先にいながら自宅にいるようにインターネットをする方法

(6/14 11:00 間違いに気付いたので大幅に直しました)

自宅のSSHd + SOCKS serverを介してインターネットにアクセスすれば,公開鍵暗号を破られない限り,自分の管理していないFirewallやProxyに通信を閲覧されることがなくなります.
また,SSHが通っていれば簡単に使えるので手軽です.

ローカル:出先(会社,研究室)のLinux
リモート:自宅のLinux

と呼ぶことにします.

まず,ローカルからリモートへSSHでトンネルを掘りましょう

ssh -D 1080 -p 22 user@jitakuhogehoge.com

ポート番号は適宜読み変えてください.

ローカルのFirefoxを以下のように設定します

SSL Proxyの項目は設定しないでください.SSLセッションは元々暗号化されているので,SOCKS通すと上手く通信できなくなります.

tcpdumpでパケットを見てみると,SOCKSを通さない場合は通信内容が丸見えです.
以下は,http://team2ch.orgを表示したときのものです.


sudo tcpdump -t -n -X -s 1000 port 80 > no_socks
cat no_socks

※一部抜粋

0x0000: 4500 028b 38bf 4000 4006 ed40 8299 0db0 E...8.@.@..@....
0x0010: 77f5 0a2f aa73 0050 6623 713b 7bc8 0a43 w../.s.Pf#q;{..C
0x0020: 8018 00b6 5868 0000 0101 080a 000d 74e6 ....Xh........t.
0x0030: 3e43 d1c0 4745 5420 2f69 6e64 6578 2e63 >C..GET./index.c
0x0040: 6769 2048 5454 502f 312e 310d 0a48 6f73 gi.HTTP/1.1..Hos
0x0050: 743a 2074 6561 6d32 6368 2e6f 7267 0d0a t:.team2ch.org..
0x0060: 5573 6572 2d41 6765 6e74 3a20 4d6f 7a69 User-Agent:.Mozi
0x0070: 6c6c 612f 352e 3020 2858 3131 3b20 553b lla/5.0.(X11;.U;

SOCKSを通せば


sudo tcpdump -t -n -X -s 1000 port 22 > socks_haita
cat socks_haita

※一部抜粋


0x0000: 4500 0104 c652 4000 3706 6a34 77f5 0a2f E....R@.7.j4w../
0x0010: 8299 0db0 a2e4 856a 628f d7eb f933 c721 .......jb....3.!
0x0020: 8018 0266 48c7 0000 0101 080a 0a5f 9a0d ...fH........_..
0x0030: 000e 0bc9 3049 7fb9 b473 7a4e 47d9 d50e ....0I...szNG...
0x0040: e8a4 15b4 ee8c 0d60 9506 c829 170e 2d26 .......`...)..-&
0x0050: 4fa2 d2e5 fc49 14c3 9f27 5b83 9a27 f5bf O....I...'[..'..
0x0060: 0368 db97 a2d1 187d f180 2f42 f631 c525 .h.....}../B.1.%
0x0070: 6fea 9341 019a 4f6a 1d7f bb0e 52ea 82fa o..A..Oj....R...

実際にパケットを見ても,通信内容について推測することは(公開鍵暗号を破らない限り)できません.
もし仮にパケット内容を暗号化している共通鍵が解読されたとしても,共通鍵は使い捨てなので,盗聴されたパケットは氷山の一角にすぎません.

ssh -Xはローカルネットワーク内であれば有効ですが,WAN越しだと描画速度の面から実用的ではありません.
この方法でSOCKSを使えば,ローカルから直接接続するのとあまり変わりない描画速度/回線速度で,Firewallを誤魔化しながら通信をすることができます.
もっとも,回線速度に関してはリモートの回線速度にも大きく依存すると考えられます.また,FirewallでSOCKSによる通信をしゃ断されたら使えないというデメリットもあります.

DDNS更新スクリプト(運用編)

運用とかそんな大層なもんじゃないですが,先月作ったスクリプトがどうなったかについて書いておきます.

# ls -lart
total 40
drwxrwsr-x 3 root staff 4096 Feb 12 23:36 ..
-rw-r--r-- 1 root staff 49 Feb 16 19:27 log~
-rw------- 1 root staff 15 Feb 16 19:27 getip~
-rw-r--r-- 1 root staff 12 Feb 16 19:27 getip_status~
-rw------- 1 root staff 793 Feb 16 20:20 vd.sh~
-rwx------ 1 root staff 802 Feb 16 21:29 vd.sh
drwx--S--- 2 root staff 4096 Feb 16 21:29 .
-rw------- 1 root staff 444 Mar 16 18:55 log
-rw-r--r-- 1 root staff 12 Mar 16 18:55 getip_status
-rw------- 1 root staff 15 Mar 16 19:20 getip

getipは10分毎に取得できているようです.logが10分毎になっていないのは,さっき手動で回したせいです.

# cat log
Tue Feb 16 19:52:03 JST 2010 -> 119.245.10.115
Tue Feb 16 20:12:26 JST 2010 -> 119.245.10.115
Tue Feb 16 20:15:11 JST 2010 119.245.10.115 ->
Tue Feb 16 20:20:01 JST 2010 119.245.10.115 ->
Tue Feb 16 20:25:01 JST 2010 -> 119.245.10.115
Tue Feb 16 20:50:01 JST 2010 -> 119.245.10.115
Wed Feb 24 14:50:04 JST 2010 119.245.10.115 ->
Wed Feb 24 15:00:04 JST 2010 -> 210.165.205.7
Tue Mar 16 18:55:12 JST 2010 210.165.205.7 -> 119.245.11.216

お世辞にも上手くlogが取れてるとは言い難いですね.原因として,IPアドレスが変化すると,一時的にifconfigのinet addr欄が空白になることが考えられます.
ただ,変更日時と変更後のIPアドレスは分かるので,さほど困ることはないです.

PCルータの性能についてですが

$ free
total used free shared buffers cached
Mem: 1034944 779284 255660 0 114268 596360
-/+ buffers/cache: 68656 966288
Swap: 2650684 76 2650608

PCルータにはメモリ1G載せてるのですが,70M程度しか使っていないようです.
CPUはセレロン2Gですが,負荷により通信が落ちることもありません.
Atomあたりでも,NICさえしっかりしたもの積めば十分な性能が出る気がします.
家庭用ルータより速くて小回りが効くので,設置場所さえ許されるのであればおすすめです.

value-domain.comのDDNSを自動で更新するスクリプト

固定IPアドレスを持ってないので,IPアドレスが変わる度value-domainにお知らせしなければなりません.
しかし,IPアドレスが変更されるとSSHも通りませんので出先だと手の施しようがなくなります.

固定IPアドレスは高いので,以下のような要件を満たすシェルスクリプトを書きました.

こうしたい:

・うちで使ってるdebian lennyで動く
・value-domainでだけ使えればいい
・crontabに登録して,10分に1回IPアドレスに変更がないか確認させる
・WAN側IPアドレスを知るのに,外部サーバに問い合わせを行わない(10分に1回問い合わせたらご迷惑でしょう?)

スクリプトのテキスト版はこちら

#!/bin/sh

# Set your account information of VALUE-DOMAIN.com
vdomain=`echo 'hogehoge.com'`;
vpass=`echo 'password'`;

# WAN port
wan_if=`echo 'ppp0'`;

# Getting the current directory of this script
current_dir=`echo $(cd $(dirname $0);pwd)`

# Get older ip address
oldip=`cat $current_dir/getip`;

# Get current ip address
`ifconfig $wan_if | grep "inet addr" | awk '{print $2}' | sed 's@addr:@@'` > $current_dir/getip;

# You can also use this line;
# wget -O $current_dir/getip "http://dyn.value-domain.com/cgi-bin/dyn.fcg?ip";

sleep 5;
newip=`cat $current_dir/getip`;

# Renew (or do not renew)
if [ "$oldip" != "$newip" ]; then
wget -O $current_dir/getip_status "http://dyn.value-domain.com/cgi-bin/dyn.fcg?d=$vdomain&p=$vpass&h=*&i=$newip";
echo "`date` $oldip -> $newip" >> $current_dir/log;
fi

$ sudo crontab -l

*/10 * * * * /bin/sh /usr/local/sbin/vd/vd.sh >/dev/null 2>&1

ファイル構成は

vd.sh       (上記スクリプト本体)
log        (IPアドレスに変更があったときに書いておくファイル)
getip       (アドレスをメモしておく,/tmpに置いた方がよかったかも)
getip_status  (最後にIPアドレスが変更されたときの,value-domain.comからの応答を書いておく)

です.

ifconfigで外側IPアドレスを取得しているので,外側IPアドレスの付与を受けているインターフェースを持つマシンでしか使えません.
まあつまり,PCルータで回す用です.

NAT内で使うには,外部サーバに頼るか,その他の工夫が必要です.
DDNS更新スクリプト(運用編)へ続く

追記@2011-02-26
意外と閲覧数が多いことに気付いたので,一部訂正&テキスト版を置きました

追記@2011-11-09
上記スクリプトをマルチアカウント版に改良してくださった方がいます.感謝.
ValueDomain用のdynamicDNS更新のBashスクリプト

既知のバグ@2011-11-09
Terminalを日本語環境で使用していると上手く動かないようです.つまり,

$ echo $LANG

を実行してja_JP.UTF-8などが表示される場合,使えないということです.(うちの環境ではen_US.utf8が表示されます)
これは,IPアドレスを取得する行,つまり

`ifconfig $wan_if | grep "inet addr" | awk '{print $2}' | sed 's@addr:@@'` > $current_dir/getip;

がコテッコテで環境依存な取得方法であることに由来しています.
動かすには,この行を改良するか言語をen_US.utf8に設定する必要があります.
外部サーバに問い合わせするのを許容するなら,例えば以下のように変更すればいいと思います.

wget -O $current_dir/getip "http://dyn.value-domain.com/cgi-bin/dyn.fcg?ip";

LAN内でSSHを使う

有限な机上スペースを効率的に使うため,SSHをインストールしました.
偉そうなこと言ってますが家が狭いだけです.

OS(参考程度に) :
SSHサーバ:Debian lenny
SSHクライアント(LAN内):Ubuntu 9.10
SSHクライアント(LAN外):Solaris9と10

SSHをインストールする前に,ルータ(iptables)の設定をしました.
当面はLAN内でのみの運用としたいので

定数に

ssh_port='22'

INPUT RULESに

$IPTABLES -A INPUT -i $wan_port -p tcp --dport $ssh_port -j DROP

としました(Port22は変えたほうがいい).

{ もっとも,SSHサーバはNAT内であり,ルータのNAT設定をしていないのだから
この行を追加しようがしまいが外から繋がらないことに変わりはない.要は気持ちの問題である.}

LAN内の端末間のFORWARDは元々許可されています.

# LAN内の他端末からのアクセスを許可
$IPTABLES -A FORWARD -s $lan_range -d $lan_range -j ACCEPT

本題.SSHをインストールします.

sudo apt-get install ssh

/etc/ssh/sshd_configを書き換えます.

sshd の設定(sshd_config)
Ubuntuでsshdの設定をしてリモートから接続できるようにする

書き換えたら

sudo /etc/init.d/ssh restart

まずはsuの制限をかける程度にして,認証に成功したら公開鍵認証に切り替えることにしました

早速,LAN内のクライアントから

$ ssh -p 22 user@hostname
The authenticity of host '[hostname]:22 ([***]:22)' can't be established.
RSA key fingerprint is ***.
Are you sure you want to continue connecting (yes/no)? yes

fingerprint取られて通常通りのPassとUserで通ります.
特に何も弄ってないのですが,X使うもの(geditとか)も動きました.

一方,LAN外から叩いてみると

ssh -p 22 user@team2ch.org
ssh: connect to host team2ch.org port 22: Connection refused

入れません.NAT設定してない上にINPUTで蹴ってるわけだから入れたらいやですが.

さて,公開鍵認証にしよう.
Password認証やらPAMやらはnoにして,公開鍵認証の項目のみyesにします.

PubkeyAuthentication yes

その後,サーバの~/.ssh/authorized_keysにクライアントの公開鍵を追記してsshをrestartすればOKです.
UbuntuからDebianのiceweaselを起動しても,そこそこ動いてくれます.

結論:これは便利だ.今まで怠けて設定してなかったことが悔やまれる.当たり前だが,ルータの設定と許可IPアドレスの範囲さえ変えれば外からもいけるわけだし.

robots.txtとBasic認証付きのサイトでwgetを使う

今日びそんな自意識過剰なセキュリティが強いんだか弱いんだか分からないサイトは滅多に存在しませんが,残念ながら遭遇してしまいました.一瞬悩んだのでメモしておきましょう.

$ wget -e robots=off -r -l 2 http://user:pass@hoge.com/index.html

または

$ wget -e robots=off -r -l 2 --http-user='USER' --http-passwd='PASS' http://hoge.com/index.html

でなんとかなります.passに!等の記号が含まれてるときは!とでもしてやればOK.

前のエントリーにもちょっと書きましたね