ホストポートへのQEMUゲストアクセスを無効にする方法

ホストポートへのQEMUゲストアクセスを無効にする方法

次のコマンドを使用してQEMU VMを実行します。

qemu-system-x86_64 -enable-kvm -m 1024 -smp 2 -hda disk.qcow2

デフォルトでは、ゲストオペレーティングシステムはインターネットにアクセスできますが、ホストオペレーティングシステムの開いているポートにもアクセスできます。ゲストOSがホストのポートにアクセスするのを防ぐにはどうすればよいですか(インターネットアクセスは制限されません)。

答え1

高度なiptables操作の経験がなく、Linuxがローカルプロセストラフィックをフィルタリングする方法の概要がない場合は、問題になる可能性があります。

あなたのモードでは、qemuはシミュレートされたNATを実行します。ゲストからのNICへのすべての呼び出しは、qemuプロセス自体によってソケット/接続/送信/受信呼び出しに変換されます。これは、接続が127.0.0.1でマシン自体によって確立されることを意味します。この時点で、別のユーザーとしてqemuを実行し、一致を追加してそのユーザーをフィルタリングできますowner

iptables -I OUTPUT -o lo -m owner --uid-owner username -m multiport --dports ports -j DROP

usernameフィルタするユーザー名はどこにあり、このコンピュータでports無効にするポートのカンマ区切りリストはどこにありますか。他のユーザーとしてqemuを実行するには、userまたは同様の方法で実行またはsudoログインする必要があります。sulogin

これがないと自分でフィルタリングされるため、ポートをフィルタリングする一般的な規則を追加すると、そのポートへのアクセスもブロックされます。

別の方法は、qemuのネットワークモードを変更することです。トラフィックをフィルタリングする良い方法は、qemuを仮想イーサネットデバイスにバインドすることです。

  • パケット転送を有効にします。

  • をインストールするには、tunctl自分が所有する仮想ネットワークインターフェイスを追加してください。

tunctl -u yourname -t qemu

rc.local(永続的なものと同じコマンドにこのコマンドを追加することを忘れないでください)

  • 無料の/ 24サブネットを割り当てるようにqemuインターフェイスを設定します(ipまたは他のオペレーティングシステム提供ツールを使用)。ifconfigこのサブネットはゲストオペレーティングシステムにも設定する必要があります。それから-net tap,ifname=qemu,script=off。ゲストオペレーティングシステムネットワークを再設定します。

qemuその後、仮想インターフェイスとして表示されるゲストOSトラフィックを簡単にフィルタリングできます。

iptables -I FORWARD -i qemu -m multiport --dports ports -j DROP

動作する必要があります。

しかし、NATは動作を停止しました。 NATを再び機能させるには、コンピュータから送信されたIPアドレスにパッチを適用するルールを追加する必要があります。eth0すべてのトラフィックが通過するインターフェイスがある場合は、NATをイネーブルにします。

iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE

答え2

-netdev user基本()ネットワークを使用している場合は、いくつかの簡単なファイアウォールルールがあることを追加したいと思います。

iptables -I OUTPUT -o lo -m owner --uid-owner qemu-user -d 127.0.0.1 -j DROP

userの下でqemuを実行する必要があることに注意しqemu-userてください。sudo -u qemu-user qemu-system-x86_64 -enable-kvm ......

これにより、ホスト上のすべてのポートを指定せずに(最初の回答のように)ゲストに表示されるのを防ぎます。宛先アドレス(ゲストがデフォルトで表示するホストのアドレス)で127.0.0.1はない理由は、10.0.2.2qemuがNATを実行する方法によるものです。

興味がある場合は、qemuがネイティブネットワーキングをどのように処理するかについての詳細は次のとおりです。

Qemuは、仮想化ネットワークカードから飛んでいるネイティブリンクレイヤパケットで完了したTCPおよびUDP接続を傍受し、、、、...を呼び出して、qemuプロセス自体で実行される対応する接続​​に変換します。socket()その間connect()、いくつsendto()recvfrom()のアドレス変換も行われます。実行されるため、および10.0.2.2への接続はそれぞれおよびへの接続10.0.2.3に変換されます。そのため、チェーンルールはqemuの接続を解除し、ホストのDNSサーバーを除いてゲストにホストを見えないようにします(そしてqemu内でエミュレートされたDHCPサーバーですが、これはすべてqemu内で行われます)。127.0.0.1127.0.0.53OUTPUT127.0.0.1

10.0.2.3ここでは、ゲストが次を使用してnslookup google.com 10.0.2.3DNSドメインを解決するときにqemuが実行するネットワーク関連のシステムコールを表示できます。

$ sudo strace -f -e trace=network -p <qemu_pid>
strace: Process 14529 attached with 10 threads
[pid 14529] socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 99
[pid 14529] sendto(99, "\236\353\1\0\0\1\0\0\0\0\0\0\6google\3com\0\0\1\0\1", 28, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, 16) = 28
[pid 14529] recvfrom(99, "\236\353\201\200\0\1\0\1\0\0\0\0\6google\3com\0\0\1\0\1\300\f\0\1"..., 1500, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, [128->16]) = 44
[pid 14529] socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = 100
[pid 14529] sendto(100, "@R\1\0\0\1\0\0\0\0\0\0\6google\3com\0\0\34\0\1", 28, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, 16) = 28
[pid 14529] recvfrom(100, "@R\201\200\0\1\0\1\0\0\0\0\6google\3com\0\0\34\0\1\300\f\0\34"..., 1500, 0, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("127.0.0.53")}, [128->16]) = 56

見て再び10.0.2.3血に変換されます127.0.0.53。ゲストがこのアドレスと通信すると、Qemuはポート53へのUDPトラフィックのみを許可するため、ホストはDNSサーバーデーモンを除いて公開されなくなります。

関連情報