FreeBSD7.3でntpdの設定/起動

ntpサーバの指定

参考: 「man 5 ntp.conf」

$ sudo vim /etc/ntp.conf
server 210.173.160.27
server 210.173.160.57
server 210.173.160.87

ntpdの起動

参考: 「man 8 ntpd」

$ sudo /usr/sbin/ntpd -p /var/run/ntpd.pid 

reboot時にntpdが起動されるようにしておく

参考: 「man 5 rc.conf」

$ sudo vim /etc/rc.conf
# ntpd
ntpd_enable="YES"

FreeBSD7.0でJailの作成

※ 書きかけ。個人的なメモ。

最新のportsツリーをダウンロード/展開しておく。

$ cd
$ fetch ftp://ftp.freebsd.org/pub/FreeBSD/ports/ports/ports.tar.gz
$ cd /usr
$ sudo tar zxf ~/ports.tar.gz

ezjailのインストール

$ whereis ezjail
ezjail: /usr/ports/sysutils/ezjail

$ sudo make install
...
mkdir -p /usr/local/etc/ezjail/ /usr/local/man/man1/ /usr/local/man/man5/ /usr/local/etc/rc.d/ /usr/local/bin/ /usr/local/share/examples/ezjail
cp -p ezjail.conf.sample /usr/local/etc/
cp -R -p examples/example /usr/local/share/examples/ezjail/
cp -R -p examples/nullmailer-example /usr/local/share/examples/ezjail/
sed s:EZJAIL_PREFIX:/usr/local: ezjail.sh > /usr/local/etc/rc.d/ezjail.sh
sed s:EZJAIL_PREFIX:/usr/local: ezjail-admin > /usr/local/bin/ezjail-admin
sed s:EZJAIL_PREFIX:/usr/local: man1/ezjail-admin.1 > /usr/local/man/man1/ezjail-admin.1
sed s:EZJAIL_PREFIX:/usr/local: man5/ezjail.conf.5 > /usr/local/man/man5/ezjail.conf.5
sed s:EZJAIL_PREFIX:/usr/local: man5/ezjail.5 > /usr/local/man/man5/ezjail.5
chmod 755 /usr/local/etc/rc.d/ezjail.sh /usr/local/bin/ezjail-admin
chown -R root:wheel /usr/local/man/man1/ezjail-admin.1 /usr/local/man/man5/ezjail.conf.5 /usr/local/man/man5/ezjail.5 /usr/local/share/examples/ezjail/
chmod 0440 /usr/local/share/examples/ezjail/example/usr/local/etc/sudoers
===>   Compressing manual pages for ezjail-3.1
===>   Registering installation for ezjail-3.1
...

設定ファイルの編集
「man ezjail.conf」を見ると、ほとんどデフォルトでOKな気がする…。「ezjail_ftphost」は近いところを指定しておいたほうがよさそう。

設定ファイルの雛形をコピーして利用する
$ sudo cp  /usr/local/etc/ezjail.conf.sample /usr/local/etc/ezjail.conf

$ sudo vim /usr/local/etc/ezjail.conf
ezjail_jaildir=/usr/jails
ezjail_ftphost=ftp.jp.freebsd.org

basejailの作成1回目。失敗した。

$ sudo ezjail-admin install
Could not fetch base from ftp.jp.freebsd.org.
  Maybe your release (7.0-RELEASE) is specified incorrectly or the host ftp.jp.freebsd.org does not provide that release build.
  Use the -r option to specify an existing release or the -h option to specify an alternative ftp server.
Querying your ftp-server... The ftp server you specified (ftp.jp.freebsd.org) seems to provide the following builds:
total 24
lrwxrwxrwx   1 600   100    10 Aug 29  2007 4.11 moved to ftp-archive -> README.TXT
lrwxrwxrwx   1 600   100    10 Oct 26  2007 5.3 moved to ftp-archive -> README.TXT
lrwxrwxrwx   1 600   100    10 Aug 29  2007 5.4 moved to ftp-archive -> README.TXT
lrwxrwxrwx   1 600   100    10 Oct 26  2007 5.5 moved to ftp-archive -> README.TXT
lrwxrwxrwx   1 600   100    10 Aug 29  2007 6.0 moved to ftp-archive -> README.TXT
lrwxrwxrwx   1 600   100    10 Oct 23  2007 6.1 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Sep 11  2008 6.2 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Apr  4  2009 6.3 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Apr  3  2010 6.4 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Apr  4  2009 7.0 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Oct  7  2009 7.1 moved to ftp-archive -> README.TXT
lrwxr-xr-x   1 root  100    10 Nov 12 01:44 7.2 moved to ftp-archive -> README.TXT
drwxr-xr-x  14 root  100   512 Mar 22  2010 7.3-RELEASE
drwxr-xr-x  14 root  100   512 Dec 25 03:45 7.4-RC1
lrwxr-xr-x   1 root  100    10 Nov 12 01:44 8.0 moved to ftp-archive -> README.TXT
drwxr-xr-x  13 root  100   512 Jul 19 21:42 8.1-RELEASE
drwxr-xr-x  13 root  100   512 Dec 25 03:46 8.2-RC1
drwxr-xr-x   8 300   300  1024 Dec  7 03:49 ISO-IMAGES
-rw-r--r--   1 600   100   637 Nov 24  2005 README.TXT
Ignore the next question, ezjail answers it for you.
Error: Package install script for base failed.

Jailホストのバージョンを7.0-RELEASEから7.3-RELEASEに上げてしまうことにする。
参考: FreeBSD 7.3-RELEASE Announcement

$ sudo freebsd-update upgrade -r 7.3-RELEASE
※ 結構時間が掛かるので気長に待つ…。

$ sudo freebsd-update install
Installing updates...
Kernel updates have been installed.  Please reboot and run
"/usr/sbin/freebsd-update install" again to finish installing updates.

$ shutdown -r now

$ freebsd-update install

$ shutdown -r now


basejailの作成2回目。成功した。

$ sudo ezjail-admin install

basejailをupdateする。同じリリース内でセキュリティパッチレベルを上げるために使用するコマンドのfreebsd-updateを利用する。

$ sudo mkdir /usr/jails/freebsd-update

$ sudo freebsd-update -b /usr/jails/basejail -d /usr/jails/freebsd-update fetch
$ sudo freebsd-update -b /usr/jails/basejail -d /usr/jails/freebsd-update install
Installing updates... done.

jail用のalias IPアドレスの付与

$ sudo ifconfig le0 alias 192.168.11.5 netmask 255.255.255.0

jailの作成

$ sudo ezjail-admin create trafficbuild.dip.jp 192.168.11.5
...
Warning: Some services already seem to be listening on all IP, (including 192.168.11.5)
  This may cause some confusion, here they are:
root     sshd       651   4  tcp4   *:22                  *:*
root     syslogd    541   7  udp4   *:514                 *:*

/etc/rc.confの編集

$ sudo vim /etc/rc.conf
# syslog関連
yslogd_flags="-b 192.168.11.4"
※ JailホストのIPアドレスを指定する。ここでは192.168.11.4# jailを自動起動
ezjail_enable="YES"

# jailのIPアドレスを起動時に割り当てる
ifconfig_le0_alias0="inet 192.168.11.5 netmask 255.255.255.0"

/etc/ssh/sshd_configの編集
詳しくは「man sshd_config」を参照。

$ sudo vim /etc/ssh/sshd_config
ListenAddress 192.168.11.4
※ JailホストのIPアドレスを指定する。ここでは192.168.11.4

再起動して設定を反映する

$ sudo shutdown -r now

IPアドレスの割り当て、jailの起動を確認

IPアドレスが設定されているか確認
$ ifconfig

jailの起動確認
$ jls 
   JID  IP Address      Hostname                      Path
     1  192.168.11.5    trafficbuild.dip.jp           /usr/jails/trafficbuild.dip.jp

手動でのjail起動/停止

$ sudo /usr/local/etc/rc.d/ezjail.sh forcestart trafficbuild.dip.jp
$ sudo /usr/local/etc/rc.d/ezjail.sh forcestop trafficbuild.dip.jp

jail内の環境整備

JIDを調べる
$ jls
   JID  IP Address      Hostname                      Path
     1  192.168.11.5    trafficbuild.dip.jp           /usr/jails/trafficbuild.dip.jp

jail内に入る (追記: 「sudo ezjail-admin console trafficbuild.dip.jp」がより正しかったかもしれない)
$ sudo jexec 1 /bin/sh

自分のアカウント追加
# vipw
※ jailホストのやつをコピーしてくれば楽(ログインシェルだけ/bin/shにしておく)

ホームディレクトリ作成
# mkdir -p /home/username
# chown -R username /home/username

sshdをjail起動時に起動させる設定を追加
# vi /etc/rc.conf
sshd_enable="YES"

jailを抜けて、jailホストをリスタート(jailをリスタートするだけでは何故かsshできなかった…)
$ sudo shutdown -r now

jailにsshできるか確認。jail以外のホストからsshログインを試みる。

hostsにjailのIPアドレスを設定
$ vi /etc/hosts
192.168.11.5 trafficbuild.dip.jp

$ ssh trafficbuild.dip.jp

とりあえずパスワードログインできるようになった。あとはauthorized_keysに公開鍵置いておく。

$ scp .ssh/id_rsa.pub  trafficbuild.dip.jp

$ ssh trafficbuild.dip.jp
$ mkdir .ssh
$ cat id_rsa.pub >> .ssh/authorized_keys


jail内でportsツリーをダウンロード

$ sudo ezjail-admin update -P

内部ではportsnapを利用している模様
初回(/usr/jails/basejail/usr/portsが存在しない場合)は以下が実行される
$ sudo portsnap fetch
$ sudo portsnap -p /usr/jails/basejail/usr/ports extract

次回(/usr/jails/basejail/usr/portsが存在する場合)は以下が実行される
$ sudo portsnap fetch
$ sudo portsnap -p /usr/jails/basejail/usr/ports update


jailホストのportツリーをjail内で共有する ← ezjailだとbasejail以下のportsツリーを使う考え方みたいなので、これは違う気がしてきた。。素直にbasejail/usr/portを使うことにする。そもそも、jail内の/usr/portsは/basejail/usr/portsを指すシムリンクとして作成されるので、やはりbasejail以下のports(portsに限らずか…)をマスタとして使用するという考え方らしい。

jailホストのportsツリーをjail内にマウントする
jail_host$ sudo mount_nullfs -o ro /usr/ports /usr/jails/trafficbuild.dip.jp/usr/ports

確認
jail_host$ df

マウントがうまくいっていたら、fstabにも追加しておく
jail_host$ sudo vim /etc/fstab
/usr/ports              /usr/local/jail1/usr/ports  nullfs ro,noauto    0   0


jail内のmake.conf編集
(書き込みが発生するディレクトリだけ、デフォルトの/usr/portsではないところにしておく)
jail# vi /etc/make.conf 
WRKDIRPREFIX=/var/tmp
DISTDIR=/var/tmp/usr/ports/distfiles
WITHOUT_IPV6="yes"

これでjail内でもportsが利用できるようになった。portsツリーはbasejailのだけメンテすればよいから楽。

TODO

jail内でportsを使えるようにする
Flavourの設定(次回以降のjail作成を楽にするための設定)

オプション > コンフィグ > デフォルト値の優先順位で設定

メモ。

#! /opt/local/bin/perl
use strict;
use warnings;

use Getopt::Long;
use Config::Simple;

my %option = (
    hoge => '',
);
Config::Simple->import_from("$ENV{HOME}/.testconfig" ,\%option);
GetOptions(
    'hoge=s' => \$option{hoge},
);


print <<"EOF";
hoge      @{[ $option{hoge} || "default_hoge_value"  ]}
EOF

踏み台サーバを介したログイン

踏み台を介したログインがめんどくさい。以下のように.ssh/configに書いておけば、直接目的のサーバにsshできるようになる(実際は踏み台サーバを介している)。
踏み台サーバでncコマンドが使用可能な状態となっていることが条件らしい。

書式

Host <直接ログインしたいサーバ>
    ProxyCommand ssh <踏み台サーバ> nc %h %p

詳しくは「man ssh_config」を参照。

example.ne.jp example.co.jp などに直接ログインしたい場合 (「ne」と「co」部分にワイルドカードを使用してマッチさせてる)
$ vi .ssh/config
Host example.??.jp
    ProxyCommand ssh fumidai.co.jp nc %h %p


これは便利。なぜ今迄調べもしなかったのか…。。

複数ファイルの共通行を抜き出す(または共通でない行を抜き出す)

(同じファイル内には同一行が無いのが前提)

共通行を抜き出すだけだったら、ワンライナーでさくっと書ける。

$ perl -nl -e 'BEGIN{$c=scalar @ARGV}; $h{$_}++; END{ for (keys %h){print if $h{$_} == $c}; }' file1 file2 file3 ...

BEGINブロック内でARGVの内容を保存してるのは、ENDブロック内では既に空だったから。
何故ENDの時点で@ARGVが空になってるかは分からない…

なぜかENDの時点では@ARGVが空になっている…
$ perl  -nl -e 'BEGIN {print scalar @ARGV}; END{print scalar @ARGV}' common_line.pl runtests.pl  file1 file2
2
0

ワンライナーがどう展開されるのかを見ても分からん…
$ perl -MO=Deparse,-p -nl -e 'BEGIN {print scalar @ARGV}; END{print scalar @ARGV}' file1 file2
2
BEGIN { $/ = "\n"; $\ = "\n"; }
LINE: while (defined(($_ = <ARGV>))) {
    chomp($_);
    sub BEGIN {
        print(scalar(@ARGV));
    }
    
    sub END {
        print(scalar(@ARGV));
    }
    ;
}
-e syntax OK

…ARGVの話は置いておいて、今回もう一つやりたかったことは、指定されたファイル中のある行が他のファイルどれか一つにでも欠けていたら、「共通でない行」として標準出力に出力するということ(言葉にすると訳分からないな…)。これはワンライナーでは難しいと思ったので、以下のコードを書いた。(汚ない…)

common_line.pl

#! /opt/local/bin/perl -w
use strict;
use Getopt::Long;

my %option = (
    reverse     => undef,
    tofile      => undef,
);

GetOptions(
    'reverse!'      => \$option{reverse},
    'tofile!'       => \$option{tofile},
) or usage();


# 1. count common lines.
my %hash;
for my $file (@ARGV) {
    open my $fh, '<', $file or die "cannot open file [$file]: $!";
    while ( defined(my $line = <$fh>) ) {
        chomp $line;
        $hash{$line}{COUNT}++;
        $hash{$line}{$file}++;
    }
}

# 2. print common line(s) or save "not" common lines to %f_hash.
my %f_hash;
for my $line (keys %hash) {
    if ($hash{$line}{COUNT} == scalar(@ARGV)) { # line that exists in all files
        next if $option{reverse};
        # print out common line(s)
        print $line, "\n";
        next;
    }
    else { # line that not exists in all files
        next if !$option{reverse};
        my @file = grep !/COUNT/, keys %{ $hash{$line} };
        for my $f (@file) {
            $f_hash{$f} .= "$line\n";
        }
    }
}

# 3. print out not common line(s)
for my $f (keys %f_hash) {
    if ($option{tofile}) { # print to FILES
        my $f_name = $f . '.not.common';
        open my $fh, '>', $f_name or die "cannot open $f_name: $!";
        print $fh $f_hash{$f};
    }
    else { # print to STDOUT
        print "[Lines that not exists in all specified files: $f]\n";
        print $f_hash{$f};
    }
}

sub usage
{
    print <<"EOF";
DESCRIPTION:
    Print lines that are common in specified files to STDOUT.
    Or do the opposite (specify --reverse option).
USAGE:
    $0 file1 file2 ...
OPTION:
    --reverse
        Print lines that are "not" common.
    --tofile (in effect only when used with --reverse option)
        Print lines to files.
EOF
    exit 1;
}

使い方

以下の3つのファイルを入力ファイルとする
$ cat a.txt 
a
b
c
$ cat b.txt
b
d
$ cat c.txt
a
b

共通行を抜き出す
$ common_line.pl a.txt b.txt c.txt
b

各ファイル毎に共通行以外を抜き出す ← これがやりたかった
$ common_line.pl a.txt b.txt c.txt --reverse
[Lines that not exists in all specified files: c.txt]
a
[Lines that not exists in all specified files: b.txt]
d
[Lines that not exists in all specified files: a.txt]
c
a

ファイルに出力
$ common_line.pl a.txt b.txt c.txt --reverse --tofile
※ 入力ファイルに「.not.common」サフィックスを付けたファイル名で出力される


もっとずっと簡単にできる悪寒がしてるけど、とりあえずこれで目的は達成できたからよしとする。