LoginSignup
14
10

More than 3 years have passed since last update.

Linux上のMultipassの仮想マシンへ外部ネットワークから接続する

Last updated at Posted at 2020-09-13

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

0. multipass使ってますか?

multipassは、仮想マシン管理ツールです。
Linuxでqemuを使いやすくしてくれる仮想化ツールです。
(WindowsだとHyper-V、Macだとhyperkitを使います)

コマンド一つ(multipass launch)で仮想マシンを簡単に動かすことができます。
簡単にLinuxの仮想マシンを使うことができるので、テストしたり練習したりCIに使ったりするのに便利です。

今はDockerなどのコンテナもあるし、いまさら仮想マシンという意見もあると思いますが、k3sを動かす時に使ったり、microk8sを動かしたり、なかなか便利なんです。

途中経過を見ないで結論に飛ぶには、7. まとめを見てください

1. しかし、困ったことが....

multipass launch した仮想マシンに接続できるのはmultipassのホストからしか接続できなくて困っていました。

image.png

198.51.100.89は、multipass内だけで利用できる内部ネットワークです。

2. んな訳ないはず

Ubuntu OSのNICからMultipass仮想マシン(QEMU)へ接続できるんだから、以下のようにルーティングを追加すれば外からのパケットだって通るはず!

image.png

(正確には外部のNICとMultipassのネットワークをOSが知っていればルーティング可能)

3. Googleで調べた

しかし、つながらないので調べてみました。

Googleで検索したら、いくつかの記事が見つかりました。

multipassでOSX上にmicro-k8sを立てる。 - nがひとつ多い。
https://nnao45.hatenadiary.com/entry/2018/12/20/085706

multipassでつくるmacOS向けのDockerd & K8s環境 - Qiita
https://qiita.com/mumoshu/items/6ff56badcfabe5ab1f49

これらによると、multipassで起動した仮想マシン内でFORWARD ACCEPTすれば良いようですが、

multipass-client
sudo iptables -P FORWARD ACCEPT

残念ながらこれでは外部から接続することができませんでした。

4. Ubuntu OS内でパケットをルーティング出来るようにする

そもそも、Ubuntu OS内でルーティングできるようにしてないとよくありません。
/etc/sysctl.d/99-sysctl.confファイルに以下を追記しました。

multipass-host:/etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward=1

それでも接続できませんでした。

5. iptableを確認する

wiresharkでパケットの流れをチェックしてみるとパケットは転送されているようですが、途中でパケットがどこかに落っこちているようです。そこでmultipassのホスト側のiptablesのフィルタールールを見てみます。

multipass-host
$ sudo iptables -nvL
Chain INPUT (policy ACCEPT 5310 packets, 1486K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  mpqemubr0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53 /* generated for Multipass network mpqemubr0 */
    2   144 ACCEPT     udp  --  mpqemubr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 /* generated for Multipass network mpqemubr0 */
    0     0 ACCEPT     udp  --  mpqemubr0 *       0.0.0.0/0            0.0.0.0/0            udp dpt:67 /* generated for Multipass network mpqemubr0 */

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  mpqemubr0 mpqemubr0  0.0.0.0/0            0.0.0.0/0            /* generated for Multipass network mpqemubr0 */
   35  3186 ACCEPT     all  --  mpqemubr0 *       198.51.100.0/24       0.0.0.0/0            /* generated for Multipass network mpqemubr0 */
   31  6005 ACCEPT     all  --  *      mpqemubr0  0.0.0.0/0            198.51.100.0/24       ctstate RELATED,ESTABLISHED /* generated for Multipass network mpqemubr0 */
    0     0 REJECT     all  --  mpqemubr0 *       0.0.0.0/0            0.0.0.0/0            /* generated for Multipass network mpqemubr0 */ reject-with icmp-port-unreachable
   90  4680 REJECT     all  --  *      mpqemubr0  0.0.0.0/0            0.0.0.0/0            /* generated for Multipass network mpqemubr0 */ reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT 2655 packets, 210K bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  *      mpqemubr0  0.0.0.0/0            0.0.0.0/0            tcp spt:53 /* generated for Multipass network mpqemubr0 */
    2   232 ACCEPT     udp  --  *      mpqemubr0  0.0.0.0/0            0.0.0.0/0            udp spt:53 /* generated for Multipass network mpqemubr0 */
    0     0 ACCEPT     udp  --  *      mpqemubr0  0.0.0.0/0            0.0.0.0/0            udp spt:67 /* generated for Multipass network mpqemubr0 */

一見正しく転送されているように見えますが、以下の行がREJECTされていて仮想マシンのIPアドレスに接続しようとするとREJECTの数値が上がります。

multipass-host
    0     0 REJECT     all  --  mpqemubr0 *       0.0.0.0/0            0.0.0.0/0            /* generated for Multipass network mpqemubr0 */ reject-with icmp-port-unreachable
   90  4680 REJECT     all  --  *      mpqemubr0  0.0.0.0/0            0.0.0.0/0            /* generated for Multipass network mpqemubr0 */ reject-with icmp-port-unreachable

どうも、このルールがパケットを落っことしているようです。

6. iptablesのルールを削除する

multipass-host
sudo iptables -D FORWARD -o mpqemubr0 -m comment --comment "generated for Multipass network mpqemubr0" -j REJECT --reject-with icmp-port-unreachable

これで繋がるようになりました。

このままだとマシンを再起動するとiptablesが元に戻ってしまいます。
以下のコマンドでiptablesを保存しておきましょう。

multipass-host
sudo apt install iptables-persistent
sudo netfilter-persistent save

7.まとめ

7-1. iptablesのルールを削除する

multipass-host
sudo iptables -D FORWARD -o mpqemubr0 -m comment --comment "generated for Multipass network mpqemubr0" -j REJECT --reject-with icmp-port-unreachable

7-2. OS内でルーティングを有効化

(最近のUbuntuではデフォルトで有効になっているかも)

multipass-host:/etc/sysctl.d/99-sysctl.conf
net.ipv4.ip_forward=1

7-3. Multipassの仮想マシン内でFORWARD ACCEPTする

(仮想マシンによる、不要なものもある)

multipass-client
sudo iptables -P FORWARD ACCEPT

8. 注意事項

このiptablesのルールを削除しても問題ないと思いますが、何か理由があってルールが存在する可能性もあるので変更には注意してください。

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10