遅ればせながら FreeBSD Advent Calendar 2018 28日目の記事です。
本来は22日目の記事だったのですが、私の不手際で投稿が伸びてしまいました。申し訳ありません。
22日の記事は私に代わってみんみんさんがZFSのsnapshotをまとめて削除するという記事を書いてくださっています。ぜひご覧いただければと思います。
今日はさくらのVPS上でFreeBSD+Jailを動かす手順を紹介しようと思います。
さくらのVPSでFreeBSD
さくらのVPS(Virtual Private Server)では、512MB~32GBの仮想サーバが利用できます。
私は1Gのプランで利用しているのですが、あまりVPSを活用しきれていない感がありました。複数台のVPSがあったりすると便利かもしれませんが、それはそれでお金がかかってしまいます。そこでFreeBSD+Jailで個別の環境を構築すれば、仮想的に複数のVPSを利用する形にできないかと考えました。
FreeBSD+Jailの環境を構築する
今回構築するJail環境
今回構築するJail環境では、以下を実現できるようにしてみましょう。
- Jailコンテナにsshでログインできること
- VNCでX11な環境が利用できること
構成図
今回は以下のような構成でJail環境を構築してみましょう。VPS上のFreeBSD(ホストOS)で 192.168.0.0/24
な内部ネットワークを用意し、そこにJailなコンテナを用意する構成にしてみます。
..................................................
. +---------+ +---------+ +---------+ .
. | Jail 01 | ... | Jail 02 | ... | Jail 05 | .
. +---+-----+ +---+-----+ +--+------+ .
. | | | .
. ----+------+--------+--------------+------- 192.168.0.0/24
..............|....................Jail環境.......
|
+-----------+--------------+
| VPS上のFreeBSD (Host OS) |
+----------+---------------+
|
[Internet]
|
+---+----+
| 自宅PC |
+--------+
Host OS側でのJail環境の構成
ホストOS側でのJail環境のディレクトリは以下のようにしてみましょう。
/
`-- jail/
|-- FBSD11_DIST/
| `-- setup_script/
| `-- base.txz
| `-- kernel.txz
`-- jail01/
`-- (Jail環境のルートディレクトリ)
環境設定
ホストOS側でのJail環境設定です。最低限、以下のファイルを設定すれば準備OKです。 /etc/rc.conf
と /etc/pf.conf
にはJail環境のネットワークをNAT構成にするための設定を記述しておきます。 /etc/jail.conf
には各Jail環境の設定を記述します。
- /etc/rc.conf
- /etc/pf.conf
- /etc/jail.conf
/etc/rc.conf
/etc/rc.conf
の設定は以下になります。 lo0
にJail環境で使用するプライベートIPをエイリアスとして割り当てておきます。
# 「さくらのVPS」コントロールパネルの「標準ホスト名」を指定します。
hostname="<VPSのホスト名>"
# 「さくらのVPS」コントロールパネルの「アドレス」に記載されているIPアドレスを指定します。
ifconfig_vtnet0="inet XXX.XXX.XXX.XXX netmask 255.255.254.0"
# 「さくらのVPS」コントロールパネルの「ゲートウェイ」に記載されているIPアドレスを指定します。
defaultrouter="XXX.XXX.XXX.XXX"
ifconfig_lo0="inet 127.0.0.1"
ifconfig_lo0_alias0="inet 192.168.0.254 192.168.0.255 netmask 255.255.255.0"
ifconfig_lo0_alias1="inet 192.168.0.10"
ifconfig_lo0_alias2="inet 192.168.0.11"
ifconfig_lo0_alias3="inet 192.168.0.12"
ifconfig_lo0_alias4="inet 192.168.0.13"
ifconfig_lo0_alias5="inet 192.168.0.14"
# NATの設定を行うため、pf(packet filter)を有効にします。
pf_enable="YES"
pf_rules="/etc/pf.conf"
pf_flags=""
pflog_enable="YES"
pflog_logfile="/var/log/pflog"
pflog_flags=""
/etc/pf.conf
Jail環境からNATするための設定は /etc/pf.conf
に記述します。また、ホストOS側から各Jail環境にsshでログインできるよう、ポートフォワード設定も記述しておきます。
ポートフォワード設定は以下のようにJail環境の設定と関連する形にしておくと管理が楽になります。以下の例では、Jail環境のプライベートIPアドレス( 192.168.0.10
)の4オクテット目の 10
をホストOS側の 2200
番ポートにインデックスの形で加算し、 2210
とする管理方法にしています。
# ホストOSの2210番ポートへのアクセスをJail環境(192.168.0.10)の22番ポートにポートフォワードする。
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2210 -> 192.168.0.10 port 22
/etc/pf.conf
の全体は以下のような感じになります。
# external interface
ext_if="vtnet0"
# internal interface
int_if="lo0"
# NW setting for internal NW
table <private> const { 192.168.0.0/24 }
# IP mascarade
nat on $ext_if inet from ($int_if) to ! <private> -> ($ext_if)
# redirect
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2210 -> 192.168.0.10 port 22
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2211 -> 192.168.0.11 port 22
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2212 -> 192.168.0.12 port 22
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2213 -> 192.168.0.13 port 22
rdr pass on $ext_if proto tcp from any to ($ext_if) port 2214 -> 192.168.0.14 port 22
# packet filter
pass in quick all
pass out quick all
$ sudo service pf restart
/etc/jail.conf
あとはJail環境の設定です。以下の1エントリが1個のJailコンテナの設定になります。
微妙なハマりどころとして、IPv6を利用せずとも ip6.addr = fe80::11;
の設定は記載しておく方が良いかもしれません。これはLL言語等で、Socketまわりの機能を利用する際に、内部的にIPv6( PF_INET6
)でソケット作成を試すものがあるようで、IPv6アドレスが振られていないと、ソケットを利用する機能が常にエラーになってしまう(!)という問題にハマってしまうためです。
test10 {
jid = 10;
path = /jail/test10;
ip4.addr = 192.168.0.10;
ip6.addr = fe80::11;
host.hostname = docs.furandon.net;
allow.raw_sockets;
exec.start = "/bin/sh /etc/rc";
# exec.stop = "/bin/sh /etc/rc.shutdown";
interface = lo0;
mount.devfs;
persist;
}
これでJailコンテナを作成する準備が整いました。
Jailコンテナを作成する
コンテナ用のFreeBSD配布物を用意する。
Jailコンテナは、特定のディレクトリ以下にFreeBSDの(最小限の)配布物を展開し、それをルートディレクトリに指定します。
以下の手順でFreeBSDの配布物をダウンロードします。
$ sudo mkdir /jail
$ sudo mkdir /jail/FBSD12_DIST
$ cd /jail/FBSD12_DIST/
$ sudo curl -O http://ftp.jaist.ac.jp/pub/FreeBSD/releases/amd64/12.0-RELEASE/base.txz
$ sudo curl -O http://ftp.jaist.ac.jp/pub/FreeBSD/releases/amd64/12.0-RELEASE/kernel.txz
コンテナの実体を用意する
次に、コンテナの実体を用意します。といってもJailコンテナのルートとなるディレクトリを作成し、FreeBSDの配布物を展開するだけです。加えて以下の例では /etc/resolv.conf
と /etc/rc.conf
の設定を行っています。
$ cd /jail
$ sudo mkdir ./jail10
$ sudo tar Jxfp FBSD12_DIST/base.txz -C ./jail10
$ sudo tar Jxfp FBSD12_DIST/kernel.txz -C ./jail10
$
$ sudo cp /etc/resolv.conf ./jail10/etc/resolv.conf
$ echo 'sshd_enable="YES"' | sudo tee -a ./jail10/etc/rc.conf
コンテナを起動する
一通りの準備が整ったので service jail [one]start <jail名>
を実行してJailコンテナを起動してみます。
$ sudo service jail onestart jail10
無事にJailコンテナが起動できました。
$ jls
JID IP Address Hostname Path
10 192.168.0.10 jail10 /jail/jail10
次に、最低限のパッケージインストールと一般ユーザを作成します。 sudo
できるようにしておきたいので、 adduser
コマンドでユーザを作成する際に、追加グループとして wheel
を指定しておきます。
$ sudo pkg --jail 10 update
$ sudo pkg --jail 10 install -y sudo bash
$ sudo jexec 10 visudo
$ sudo jexec 10 adduser
Username: freebsd
Full name:
Uid (Leave empty for default):
Login group [freebsd]:
Login group is freebsd. Invite freebsd into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh bash rbash nologin) [sh]: bash
Home directory [/home/freebsd]:
Home directory permissions (Leave empty for default):
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username : freebsd
Password : *****
Full Name :
Uid : 1001
Class :
Groups : freebsd wheel
Home : /home/freebsd
Home Mode :
Shell : /usr/local/bin/bash
Locked : no
OK? (yes/no): yes
adduser: INFO: Successfully added (freebsd) to the user database.
Add another user? (yes/no): no
Goodbye!
sshでログインできるようにする
ローカルPCの ~/.ssh/config
に以下の設定を追加し、Jailコンテナにsshでログインできるようにします。
VPS上のホストOSの2210番ポートからJailコンテナの22番ポートにリダイレクトされる形になります。
Host jail10
# HostNameには、「さくらのVPS」コントロールパネルの
# 「アドレス」に記載されているIPアドレスを指定します。
HostName XXX.XXX.XXX.XXX
Port 2210
User freebsd
以下のようにsshでログインできることが確認します。
$ ssh jail10
Last login: Thu Dec 27 21:46:08 2018 from :0
FreeBSD 12.0-RELEASE r341666 GENERIC
Welcome to FreeBSD!
Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories: https://www.FreeBSD.org/security/
FreeBSD Handbook: https://www.FreeBSD.org/handbook/
FreeBSD FAQ: https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums: https://forums.FreeBSD.org/
Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with: pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.
Show the version of FreeBSD installed: freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages: man man
FreeBSD directory layout: man hier
Edit /etc/motd to change this login announcement.
"man security" gives very good advice on how to tune the security of your
FreeBSD system.
[freebsd@jail10 ~]$
VNCでも接続できるようにする
続けてVNCでもJailコンテナに接続できるように設定してみます。まずは必要なパッケージをインストールします。
[freebsd@jail10 ~]$ sudo pkg install -y tigervnc-server tigervnc-viewer xauth xterm icewm
[freebsd@jail10 ~]$ sudo pkg install -y ja-uim-mozc uim-gtk ja-font-sazanami
[freebsd@jail10 ~]$ sudo pkg install -y leafpad
~/.vnc
ディレクトリ以下にデフォルト設定ファイルを生成するため、VNCサーバの起動・停止を行います。
(なのでここでは単にVNCを起動して停止するだけ)
[freebsd@jail10 ~]$ vncserver :0
[freebsd@jail10 ~]$ vncserver -kill :0
~/.vnc/xstartup
に以下を追記します。
# 生成されたファイルではtwmが起動する記述になっているのでコメントアウトする。
#twm &
export GTK_IM_MODULE=uim
export QT_IM_MODULE=uim
export XMODIFIERS=@im=uim
export XIM=uim
/usr/local/bin/mozc start
uim-xim &
exec icewm
改めてVNCサーバを起動します。
[freebsd@jail10 ~]$ vncserver :0
ローカルのPCから接続する場合は、以下のようにsshの -L
オプションでVNCの通信路をトンネリングすると良いかと思います。
VNC自体はデータを暗号化しないので、sshのトンネリングで暗号化しつつ、Jailコンテナへのポートフォワーディング設定も一緒に行える形になるのでおススメの方法です。
$ ssh -L 5900:localhost:5900 jail10
ローカルPCからはVNCクライアントで vnc://localhost:5900
に接続することでJailコンテナ上のVNCに接続できます。
これでJailコンテナへのssh接続とVNCによるGUI環境の構築まで行えました。
まとめ
さくらVPS上でFreeBSDを動かし、さらにJail環境を構築してVPSを仮想の仮想(?)的に複数台あるような形で利用する手順を紹介しました。
今回のJail環境は手動で構築する方法を紹介していますが、ある程度利用方法が固まったらスクリプト等で定型的な処理を行わせるとよりVPCを使い倒せるかと思います。