FreeBSDでRubyをビルドする

やること

FreeBSDRubyを自分でビルドしてインストールする。

Jail作成

インストール先のJailを作成する。

cd
mkdir /var/jail/rubybuild
bsdinstall jail /var/jail/rubybuild
cat << 'EOF' > jail-rubybuild.conf
rubybuild {
  path = "/var/jail/rubybuild";
  host.hostname = "rubybuild";
  # とりあえずIPアドレスはホストと同じものにしておく。
  ip4.addr = "172.26.11.142";
  persist;
}
EOF
jail -c -f jail-rubybuild.conf

パッケージのインストール

#/dev/nullなどをつかうコマンドのために/devを用意する。
mount -t devfs -o ruleset=2 devfs /var/jail/rubybuild/dev
pkg -j rubybuild update
pkg -j rubybuild install libedit libyaml bison libffi

Rubyソースコードダウンロード&コンパイル

configureで--with-*-dirで/usr/localを指定するのがポイント。

jexec rubybuild /bin/tcsh
cd ~/
fetch --no-verify-peer https://cache.ruby-lang.org/pub/ruby/2.6/ruby-2.6.4.tar.gz
sha256 ruby-2.6.4.tar.gz
tar xf ruby-2.6.4.tar.gz && cd ruby-2.6.4
./configure --prefix=/opt/ruby-2.6.4 --enable-libedit --with-libedit-dir=/usr/local --with-libyaml-dir=/usr/local --with-libffi-dir=/usr/local --without-gdbm --disable-install-doc
make
make install

動作確認

# /opt/ruby-2.6.4/bin/ruby --version
ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-freebsd12.0]

JJUG CCC 2019 Springの懇親会でもらったOracle Code Cardを使ってみる

やること

JJUG CCC 2019 Springの懇親会でもらったOracle Code Cardを使ってみる。

f:id:rixwwd:20190605203305j:plain
Code Card

準備

とりあえず、この辺を読んで準備する。

Fn Serverを用意する

この解説によると、JSONをCode Cardに返すことができればよいみたい。 JSONを返すだけなら、適当なWebサーバーでもOKなのだが、JavaでFunctionを作ってみる。 Fn Serverは、Oracle CloudにLinux Instanceを作れって書いてあるが、Ubuntu Serverにインストールした。

  1. 普通にUUbuntu Server 18.04 LTSをインストールする
  2. Dockerは最新のDokcerをインストールする。
  3. Fnはこの手順でインストールする。

Fn ServerにAppをデプロイする。

アプリはGithubにコミットした。 github.com

git clone https://github.com/rixwwd/mycodecard.git
cd mycodecard
fn deploy --create-app --local --all

こうすると結果が返ってくるのがわかる。

$ curl http://localhost:8080/t/mycodecard/mycodecard
{"template":"template1","title":"My Code Card","subtitle":"Duke","bodytext":"Hello world","icon":"duke","backgroundColor":"white"}

Code Cardの設定

USBでPCに接続してscreenで接続する。

sudo screen /dev/ttyUSB0 115200

横の電源スイッチをONにして、2つのボタンを同時に押すと設定ができるようになる。

Code CardにWifiの設定

Code Cardのの設定モード?になったら以下を入力する。

ssid=myssid
password=wifipassword

Code Cardのボタンを押した時に呼ばれるURLの設定

Wifiの設定に続いて、以下を入力する。この場合は、ボタンAを短く押した時のURL。(1:短く押した時、2:長く押した時)

buttona1=http://192.168.1.14:8080/t/mycodecard/mycodecard

設定できたら、ボタンを押した時の動作確認を行う。設定モード?のままで以下を入力するとボタンAを短く押した時の動作をシミュレートできる。 設定モードではボタンを押しても効かず、設定モードを抜けるのは面倒なので、これで確認する。

shortpressa

エラーの対処

これで動くと見せかけでエラーになる。

Unexpected response: HTTP/1.0 200 OK

調べてみると、HTTP/1.0のレスポンスが返ってきたときはエラーになる。 Githubのこのコミットではエラーが出ないように変更されているが、使っているCode Cardはちょっと古いやつなのかもしれない。

そこで、Nginxをリバースプロキシとして、HTTP/1.0でレスポンスを返されないようにした。 ちなみに、Code CardからのHTTPリクエストをtcpdumpで確認するとHTTP/1.0で送っている。自分で送ったバージョンを受け取れないなんて残念。

nginxの設定は、

Nginx reverse proxy settings for fn server.

nginxはDockerでサクッと準備した。

docker run --rm -v $HOME/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 nginx

再度Code Cardの設定をする。今度はnginxの経由のURLに変更した。

buttona1=http://192.168.1.14/t/mycodecard/mycodecard

これでとりあえず動いた。 結果を表示するだけだけど、電源の供給がなくても表示したまま。

ひかり電話のホームゲートウェイにFreeBSDなルーターを接続する

やること

ひかり電話のホームゲートウェイFreeBSDルーターを接続して、

  1. DHCPv6で/60のIPv6のprefixをHGWからもらう
  2. RAで/64のprefixを配布する

構成

+--------+        +---------+       +---------+
|   HGW  |        | FreeBSD |       | Xubuntu |
|        +--------+         +-------+         |
+--------+        +---------+       +---------+
  • HGWはDHCPv6 PDで/56をもらう。
  • FreeBSDのHGW側のインターフェースは、HGWからのRAを元にアドレスを設定する。(FreeBSDはRAを受信する)
  • FreeBSDXubuntu側のインターフェースは、HGWからのDHCPv6 PDでもらった/60を元にアドレスを設定する。(FreeBSDはDHCPv6のIA_PDの要求を送る)
  • XubuntuFreeBSD側のインターフェースは、FreeBSDからのRAを元にアドレスを設定する。(FreeBSDはRAを送信する)

FreeBSDのインターフェースは、

  • HGW側が、vtnet0
  • Xubuntu側が、vtnet1

とりあえずルーター用の設定

echo 'ipv6_activate_all_interfaces="YES"' >> /etc/rc.conf
echo 'ifconfig_vtnet0_ipv6="inet6 accept_rtadv" >> /etc/rc.conf
echo 'ifconfig_vtnet1_ipv6="inet6 -accept_rtadv" >> /etc/rc.conf
echo 'ipv6_cpe_wanif="vtnet0" >> /etc/rc.conf
echo 'ipv6_gateway_enable="YES" >> /etc/rc.conf

以下の設定をしておかないと、チェックサムが正しく計算されなくてうまく動かなかった。これに気がつくのに時間がかかった。 ハードウェアによるチェックサムの計算等はやらないようにしておく。

echo hw.vtnet.csum_disable=1 >> /boot/loader.conf
echo hw.vtnet.tso_disable=1 >> /boot/loader.conf
echo hw.vtnet.lro_disable=1 >> /boot/loader.conf

vtnetではない場合は、ifconfigでも設定可能。rc.confに書いておくと起動時に設定される。

ifconfig vtnet0 -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro
ifconfig vtnet1 -rxcsum -txcsum -rxcsum6 -txcsum6 -tso -lro

設定しておかないと、tcpdumpでchecksumがincorrectになる。

01:05:47.438901 IP6 (flowlabel 0xca7c6, hlim 64, next-header TCP (6) payload length: 40) 2001:0db8:1234:5678:1234:5678:0000:001.34824 > 2001:0db8:1234:5678:1234:5678:0000:0002.3000: Flags [S], cksum 0x29e4 (incorrect -> 0xb731), seq 4096995977, win 64800, options [mss 1440,sackOK,TS val 1028813372 ecr 0,nop,wscale 7], length 0

DHCPv6で/60のIPv6のprefixをHGWからもらう

FreeBSDには標準でIPv6対応のDHCPクライアントが入っていないため、インストールする。

pkg install dhcp6

設定ファイルを作る。

# vtnet0に要求を出して、戻ってきたらvtnet1に設定する。/60をもらえるので、4ビット分IDをつけて、/64を配下に割り当てる。
cat <<EOF > /usr/local/etc/dhcp6c.conf
interface vtnet0 {
  send ia-pd 0;
  send rapid-commit;
};

id-assoc pd 0 {
  prefix-interface vtnet1 {
    sla-id 0;
    sla-len 4;
  };
};
EOF

起動時に動くようにする。&起動

echo 'dhcp6c_enable="YES"' >> /etc/rc.conf

# vtnet0はHGWに接続しているインターフェース
echo 'dhcp6c_interfaces="vtnet0"' >> /etc/rc.conf

service dhcp6c start

RAで/64のprefixを配布する

RAのデーモンを起動する。

echo 'rtadvd_enable="YES"' >> /etc/rc.conf

# vtnet1はRAする側のインターフェース
echo 'rtadvd_interfaces="vtnet1"' >> /etc/rc.conf

# raflagsはDNSサーバーのアドレスをDHCPで配布する用。
cat << EOF > /etc/rtadvd.conf 
vtnet1:\
       :raflags="o":\
       :prefixlen#64:
EOF
service rtadvd start

DHCPDNSサーバーのアドレスを配布する

echo 'option domain-name-servers 2606:4700:4700::1111;' > /usr/local/etc/dhcp6s.conf
echo 'dhcp6s_enable="YES"' >> /etc/rc.conf
echo 'dhcp6s_interface="vtnet1"' >> /etc/rc.conf
service dhcp6s start

もし、最後の起動のところで、

failed to open /usr/local/etc/dhcp6sctlkey: No such file or directory

になった場合は、このファイルを作成する。

openssl rand -base64 -out /usr/local/etc/dhcp6sctlkey 16

NanoPi NEO2用のNanoBSDのSDイメージにmDNSResponderを入れる

やること

NanoPi NEO2用のNanoBSDのSDイメージにmDNSResponderを入れる。 DHCPIPアドレスを割り当てる環境下で、sshで接続するときにIPアドレスがわからなくなってnmapで探していたのを解消する。

pkgでmDNSResponderを入れる

# SDをマウント。
mkdir /tmp/nanopi-root
mount /dev/da0s2a /tmp/nanopi-root

# chrootしたときに名前解決できないのを防ぐ?(crochetのスクリプトの真似)
cp -i /etc/resolv.conf /tmp/nanopi-root/etc/

# ルートディレクトリを指定してpkgを実行する
pkg -c /tmp/nanopi-root install -y -r FreeBSD mDNSResponder mDNSResponder_nss howl
rm -i /tmp/nanopi-root/etc/resolv.conf

設定

# 設定ファイルのパーティションをマウント
mkdir /tmp/nanopi-cfg
mount /dev/da0s2d /tmp/nanopi-cfg

# 設定書き換え
cp -i /tmp/nanopi-root/etc/nsswitch.conf /tmp/nanopi-cfg
sed -i -e 's/^hosts: files dns/hosts: files mdns dns/' /tmp/nanopi-cfg/nsswitch.conf

# 自動起動するようにしておく
echo 'mdnsd_enable="YES"' >> /tmp/nanopi-cfg/rc.conf
echo 'mdnsresponder_enable="YES"' >> /tmp/nanopi-cfg/rc.conf

crochetで作ったNanoBSDは/conf/base/etc/localに/usr/local/etcのコピーを持っているので、コピーする。この辺りの詳細はdiskless(8)参照。

cp -pv /tmp/nanopi-root/usr/local/etc/rc.d/mdnsd \
   /tmp/nanopi-root/usr/local/etc/rc.d/mdnsresponderposix \
   /tmp/nanopi-root/usr/local/etc/rc.d/mdnsresponder \
   /tmp/nanopi-root/conf/base/etc/local/rc.d

後始末

umount /tmp/nanopi-cfg
umount /tmp/nanopi-root

pingでDUP!って出る件の続き

少しまえから気になっていた、pingDUP!って出る件について。

rixwwd.hatenablog.jp

原因は、Aterm WG1200HSっぽい。

pingの元は、ブリッジモードで動作しているWS1200HSにWifiで接続している。 WS1200HSのWANポートにHUBを接続していて、そのHUBにpingの宛先がある。

WS1200HSを別のやつに取り替えたら、DUPは出なくなった。そして元に戻すとまたDUP!ってなる。

WS1200HSをルーターモードにして、WANポートではない普通のポートをHUBに接続してみたら、DUPにはならなかった。今のところは。 というわけでこの構成で放置して様子を見る。

KVMのためのブリッジ作成

やること

KVMで使うためのブリッジを作る。 KVM仮想マシンからホストと同じネットワークにアクセスしたい。

コマンド

nmcli c add type bridge ifname mybridge con-name mybridge autoconnect yes stp no multicast-snooping no
nmcli c up mybridge
nmcli c add type bridge-slave ifname enp0s31f6 master mybridge
nmcli c up bridge-slave-enp0s31f6

ブリッジができたら

KVM仮想マシンNICにブリッジを指定する。