適当なところでWikiに移動したほうが良さそうな分量になっているな。
概要:
よくつかわれる﹁ftpサーバーを使ったデータのやり取り﹂はパスワードを平文で送信するため、仕事のデータをやり取りする場合に機密を確保する事が保証できない。
そしてデータ転送のport番号が不定なので、サーバーのファイアーウォール設定も緩くしてしまいがち。
またパスワードの管理コストも無視できない。覚えやすい脆弱なパスワードをつけて運用してしまうことも良くある。
そこで、暗号化したSCPを使ってftpと同様にデータのやり取りが出来るWinSCPというソフトを使ってもらうことにする。
認証はパスワードは使わずに、OpenSSHの公開鍵方式を使うことで覚えやすいパスワードを発行してしまうことを回避できる。
ただし単純にWinSCPを使ってもらうだけでは、proftpdなどで可能なアカウントごとのchrootが出来ない。
*1
そこでサーバー側に
scponly_
というシェルをインストールしてchrootを実現することにする。
外部の人にはクライアントソフトとして
WinSCP 3.4.2_
を使用してもらう。
(20040116追記:WinSCP 3.5が出ました。出来るだけ最新版で試して問題が出ないかどうか確認して使ってください)
Mac OS Xを使っている人には
Fugu - A Mac OS X SFTP, SCP and SSH Frontend._
を使ってもらう。
ftpと比較した場合:
WinSCP + scponlycの弱点
- 転送速度がftpより多少遅い(CPUパワー依存?)
- scponlycサーバーよりもftpサーバーのほうが実稼動が多い(未知のバグがあるかも)
- chrootツリーのアップデートがメンドクサイ
- パスワードが漏れて不正アクセスされる可能性は無い
- パスワードという記憶に頼った認証方法ではなく、秘密鍵ファイルを使った認証になるので、ファイルの物理管理をしっかりするだけで済む
- 機密性の強度はOpenSSHに依存
- zlib圧縮が使えるので、画像ファイルやテキストなどは帯域を節約して転送できる(可能性がある)
- サーバーのファイアーウォールは、port 22だけを空けて管理すれば良いので非常に楽
portsツリーでscponlyをchrootサポートでビルドする:
cd /usr/ports/shells/scponly
portupgradeでもKNOBが付くように/usr/local/etc/pkgtools.confのMAKE_ARGS欄に
make -DWITH_SCPONLY_CHROOT -DWITH_SCPONLY_WINSCP install個人的に-DWITH_SCPONLY_RSYNCも指定している。
portupgradeでもKNOBが付くように/usr/local/etc/pkgtools.confのMAKE_ARGS欄に
'shells/scponly' => '-DWITH_SCPONLY_CHROOT -DWITH_SCPONLY_RSYNC -DWITH_SCPONLY_WINSCP',を書くことを忘れずに。
/etc/shellにscponlycを追加する:
echo `which scponlyc` >> /etc/shellsついでにchroot無しの普通のscponlyも追加しておいても良いと思う。
echo `which scponly` >> /etc/shells
winscpグループの追加:
サーバー側のファイルの読み書き用にWinSCP共通グループの「winscp」を作る。gid 40000は例。
pw groupadd winscp -g 40000
/etc/pw.confを設定する:
scponlyでデータのやり取りをするアカウントは、uidをずらしておいたほうが管理しやすい。
下記の数値とhomeは例。
下記の数値とhomeは例。
minuid 50000 mingid 50000 home /path/to/winscp_jail/home/ shellpath /usr/local/sbin defaultshell scponlyc
setup_chroot.shをメンテ用に退避しておく:
work/scponly-3.8/config.hとwork/scponly-3.8/setup_chroot.shを、今後のアカウント追加用に${HOME}/scponly/とかに退避しておく。
mkdir ~/scponly cp work/scponly-3.8/config.h ~/scponly/ cp work/scponly-3.8/setup_chroot.sh ~/scponly/
setup_chroot.shにpatch:
長くなったので下記参照。
アカウントを追加してchrootツリーを作成する:
cd ~/scponlyしてsh setup_chroot.shする。
patchを当てたスクリプトの場合は、upload directoryも入力する。 後日にアカウントを追加することになったら、退避したconfig.hとsetup_chroot.shが有れば同様の手順で可能。
enter the home directory you wish to set for this user:でchrootツリーのディレクトリを入力。
Install for what username?でアカウント名を入力。
patchを当てたスクリプトの場合は、upload directoryも入力する。 後日にアカウントを追加することになったら、退避したconfig.hとsetup_chroot.shが有れば同様の手順で可能。
取引先に公開鍵と秘密鍵を作成してもらう:
公開鍵/秘密鍵生成 for OpenSSH2_
を見てもらい、puttygen.exeで作成してもらう。
パスフレーズ管理とかPageant.exeで便利に使う方法とかは関与しない。(調べるためのポインタを提示しておくのも有りかも?)
公開鍵だけメールでテキストとして送ってもらう。
パスフレーズ管理とかPageant.exeで便利に使う方法とかは関与しない。(調べるためのポインタを提示しておくのも有りかも?)
公開鍵だけメールでテキストとして送ってもらう。
貰った公開鍵を.ssh/authorized_keysに登録する:
ssh-keygen -X -f 貰ったputty公開鍵テキストで変換できる。
変換した公開鍵を作成したアカウントの.ssh/authorized_keysに追記する。
WinSCPでログインしてもらう:
WinSCPで、scponlyサーバーのFQDNもしくはIPアドレス・アカウント名・秘密鍵を指定してログインすると、パスフレーズを聞かれるので入力します。
ファイルのやり取りが出来ます。
場合によりWinSCPの設定/SSHのプロトコルオプションの「圧縮を有効」をオンにするのを忘れずに。
ファイルのやり取りが出来ます。
場合によりWinSCPの設定/SSHのプロトコルオプションの「圧縮を有効」をオンにするのを忘れずに。
サーバー側ではSambaでchrootツリーを共有する:
WinSCP chrootツリーを読み書きするアカウントは、winscpグループに所属してもらうように設定します。
smb.confの設定で。
[winscp] available = yes comment = WinSCP on %h browseable = yes writeable = yes valid users = @winscp force create mode = 0664 force directory mode = 0775 create mode = 775 directory mode = 775 force group = winscp veto files = /.ssh/usr/bin/etc/lib/ path = /path/to/winscp_chroot/などとして公開する。 [global]のcoding system = は、2.2.8系だったらEUCが良いのではないかと思う。 でもファイル名に日本語や全角は使わないほうが無難。 veto files = /.??*/*.{*}/ をglobalに追加したり。このへんはsamba.gr.jpのKB参照。
サーバー側からWinSCPを使う:
shellを/usr/local/bin/scponlyにしたアカウントなら、chrootしないでディレクトリを上位まで移動できます。
WinSCP管理担当のアカウントを作って、WinSCPでメンテをしてもらうという手もあります。
WinSCP管理担当のアカウントを作って、WinSCPでメンテをしてもらうという手もあります。
make worldしたら、WinSCPツリーもアップデートする:
退避しておいたconfig.hを元に、chrootツリーで使用しているファイルを割り出す。
grep '#define PROG_' config.h | /usr/bin/cut -f2 -d\" | grep -v ^cd$するとバイナリが列記される。 依存ライブラリも表示する必要が有るので、下記のlib.shを実行して確認する。 FreeBSD 4.9R-p1でRSYNC付きで実行したところ
/usr/lib/libc.so.4 /usr/lib/libcrypto.so.3 /usr/lib/libssh.so.2 /usr/lib/libz.so.2 /usr/libexec/ld-elf.so.1が依存ライブラリとして検出された。 ちなみにlibc.so.4とld-elf.so.1にschgフラグが立っているので
chflags noschg usr/lib/libc.so.4 chflags noschg usr/libexec/ld-elf.so.1などとしてフラグを落としておかないと削除も更新もできない。 またsysctl kern.securelevelが1以上だとフラグが落とせないので、/etc/rc.confでkern_securelevel_enable="NO"にした状態で再起動してsecurelevelを-1にしてメンテする必要がある。 (まぁmake installworldするときはそうしているだろうけど)
その他雑多なテクニック:
WinSCP chroot用のスケルトンを/usr/local/scponly/skel/とかに用意しておいて。pw useraddの時にpw.confのskeltonで指定するとか。
BSDHound: Setting up scponly - limited shell for secure file transfers_:
参考サイト
setup_chroot.shのpatch:
えらいadhocな適当patchなので理解せずに使ったら痛い目にあうかも。
変更点
変更点
- chrootツリーのルートパーミッションを555に変更
- 所有者をアカウントに変更
- incomingディレクトリをupload directoryとして入力指定可能にした
- ダウンロード用ディレクトリを「to_ユーザー名」として作成する
- authorized_keysで公開鍵を置くために.sshディレクトリを500で作成
- アップロード・ダウンロードディレクトリをwinscpクループにして書き込み可能にした
- syslogの時刻がUTCになってしまうので、localtimeをインストールするようにした
--- /usr/ports/shells/scponly/work/scponly-3.8/setup_chroot.sh Thu Jan 8 04:42:17 2004 +++ setup_chroot.sh Thu Jan 8 04:42:50 2004 @@ -98,6 +98,12 @@ fail "need to specify a username" fi +echo -n "Please input the name of a upload directory: " +read uploaddir +if [ "x$uploaddir" = "x" ]; then + fail "need to specify a upload directory" +fi + /usr/bin/install -c -o root -g wheel -d $targetdir /usr/bin/install -c -o root -g wheel -d $targetdir/usr /usr/bin/install -c -o root -g wheel -d $targetdir/usr/bin @@ -158,14 +164,25 @@ fi fi -chown 0:0 $targetdir +chown $targetuser $targetdir +chgrp $targetuser $targetdir +chmod 555 $targetdir +mkdir $targetdir/.ssh if [ -d $targetdir/.ssh ]; then - chown 0.0 $targetdir/.ssh + chown $targetuser:$targetuser $targetdir/.ssh + /usr/bin/touch $targetdir/.ssh/authorized_keys + chown $targetuser:$targetuser $targetdir/.ssh/authorized_keys + chmod 0500 $targetdir/.ssh fi -if [ ! -d $targetdir/incoming ]; then - echo -e "\ncreating $targetdir/incoming directory for uploading files" - /usr/bin/install -c -o root -g wheel -o $targetuser -d $targetdir/incoming +if [ ! -d $targetdir/$uploaddir ]; then + echo -e "\ncreating $targetdir/$uploaddir directory for uploading files" + /usr/bin/install -c -m 775 -g winscp -o $targetuser -d $targetdir/$uploaddir +fi + +if [ ! -d $targetdir/to_$targetuser ]; then + echo -e "\ncreating $targetdir/to_$targetuser directory for downloading files" + /usr/bin/install -c -m 775 -g winscp -o root -d $targetdir/to_$targetuser fi # the following is VERY BSD centric @@ -179,3 +196,6 @@ fi +if [ -f /etc/localtime ]; then + /usr/bin/install -c -m 444 -o root -g wheel /etc/localtime $targetdir/etc/localtime +fi
lib.sh:
setup_chroot.shから抜粋しただけのスクリプト。依存ライブラリを表示するだけ。
echo部分をchflags noschgにしても良いんじゃないかな。
#!/bin/sh # # the following is a list of binaries that will be staged in the target dir BINARIES=`/usr/bin/grep '#define PROG_' config.h | /usr/bin/cut -f2 -d\" | /usr/bin/grep -v ^cd$` LIB_LIST=`/usr/bin/ldd $BINARIES 2> /dev/null | /usr/bin/cut -f2 -d\> | /usr/bin/cut -f1 -d\( | /usr/bin/grep "^ " | /usr/bin/sort -u` LDSOFOUND=0 if [ -f /usr/libexec/ld.so ]; then LIB_LIST="$LIB_LIST /usr/libexec/ld.so" LDSOFOUND=1 fi if [ -f /lib/ld-linux.so.2 ]; then LIB_LIST="$LIB_LIST /lib/ld-linux.so.2" LDSOFOUND=1 fi if [ -f /usr/libexec/ld-elf.so.1 ]; then LIB_LIST="$LIB_LIST /usr/libexec/ld-elf.so.1" LDSOFOUND=1 fi if [ $LDSOFOUND -eq 0 ]; then fail i cant find your equivalent of ld.so fi /bin/ls /lib/libnss_compat* 2>&1 > /dev/null if [ $? -eq 0 ]; then LIB_LIST="$LIB_LIST /lib/libnss_compat* /lib/ld.so" fi if [ "x$LIB_LIST" != "x" ]; then for lib in $LIB_LIST; do echo $lib done fi
*1: OpenSSHにchroot patchを当てるという方法もある。
[ コメントする ]