<div dir="ltr"><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-size:12.8px">Yep!<br></span><span style="font-size:12.8px">That's actually a known bug that has been there "forever". It has always<br></span><span style="font-size:12.8px">been brought up in the context of "I want communication between my NATed<br></span><span style="font-size:12.8px">networks, and it only works in one direction!", rather than "I want to<br></span><span style="font-size:12.8px">block communication between my NATed networks, but it gets past in one<br></span><span style="font-size:12.8px">direction!". When people learn that it's (kind of) blocked, they work<br></span><span style="font-size:12.8px">around it by adding a new network that is shared by all the guests.<br></span><span style="font-size:12.8px">Because all of the reports have been in this direction, fixing it<br></span><span style="font-size:12.8px">properly has been very low on (my) priority list.</span></blockquote><div><br></div><div><br></div><div>Thanks for confirming the bug as I suspected, Laine! I knew it was too good to be true that I'd be the first to discover this. Thanks for your huge help, Martin.</div><div><br></div><div>I tried searching for this age-old you may be speaking of and I was only able to find this:</div><div><a href="https://bugzilla.redhat.com/show_bug.cgi?id=533193" target="_blank">https://bugzilla.redhat.com/sh<wbr>ow_bug.cgi?id=533193</a>   </div><div><br></div><div>Also found another somewhat-related bug affecting iptables (port-forwarding to VM):<br><a href="https://bugzilla.redhat.com/show_bug.cgi?id=1079088" target="_blank">https://bugzilla.redhat.com/sh<wbr>ow_bug.cgi?id=1079088</a> <br><br><br>If it's not too much trouble, can you provide me the ID number so I can track it?</div><div><br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span style="font-size:12.8px">Aside from the extra packet processing overhead caused by the high<br></span><span style="font-size:12.8px">number of rules needed (which may be completely insignificant), and the<br></span><span style="font-size:12.8px">necessity to add/remove rules at specific labels rather than just<br></span><span style="font-size:12.8px">inserting them all at the beginning, there is the issue that currently<br></span><span style="font-size:12.8px">each iptables rule added for a libvirt network is dependent only on that<br></span><span style="font-size:12.8px">network, so it's simple to determine which rules to remove when a<br></span><span style="font-size:12.8px">network is destroyed. If we start adding rules that are dependent on two<br></span><span style="font-size:12.8px">networks, then proper cleanup will be more complicated.</span></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br style="font-size:12.8px"><span style="font-size:12.8px">None of that should prevent a properly motivated person from writing the<br></span><span style="font-size:12.8px">code to do it, of course!</span></blockquote><div><br></div><div><br></div><div>At least now I know this is quite feasible to fix. Thank you both for the well-elaborated responses.</div><div><br></div><div><br></div><div>Cheers,</div><div><br></div><div>-Travis</div><div> </div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"></blockquote></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 20, 2017 at 12:46 PM, Laine Stump <span dir="ltr"><<a href="mailto:laine@laine.org" target="_blank">laine@laine.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 06/20/2017 05:27 AM, Martin Kletzander wrote:<br>
> On Tue, Jun 20, 2017 at 10:05:19AM +0200, Martin Kletzander wrote:<br>
>> On Tue, Jun 20, 2017 at 02:26:59AM -0400, Travis S. Johnson wrote:<br>
>>> Hello,<br>
>>><br>
>>> I came across an interesting problem in my home lab a few weeks ago<br>
>>> as I'm<br>
>>> prepping for my RHCE exam using Michael Jang study guide. I've been<br>
>>> at this<br>
>>> for days now, and I still can't wrap my head around how two or more<br>
>>> virtual<br>
>>> networks in default NAT configuration are even allowed to communicate<br>
>>> with<br>
>>> each other despite what the libvirt documentation said.<br>
>>><br>
>>><br>
>>> Here's the excerpt I'm referring to in the wiki link here:<br>
>>> <a href="http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections" rel="noreferrer" target="_blank">http://wiki.libvirt.org/page/<wbr>Networking#Forwarding_<wbr>Incoming_Connections</a>:<br>
>>><br>
>>>> By default, guests that are connected via a virtual network with<br>
>>>> <forward<br>
>>>> mode='nat'/> can make any outgoing network connection they like.<br>
>>>> Incoming<br>
>>>> connections are allowed from the host, and from other guests<br>
>>>> connected to<br>
>>>> the same libvirt network, but all other incoming connections are<br>
>>>> blocked by<br>
>>>> iptables rules.<br>
>>><br>
><br>
> I did not read this properly...<br>
><br>
>>><br>
>>> Also here's another assertion from 'The virtual network driver'<br>
>>> section in<br>
>>> <a href="http://libvirt.org/firewall.html" rel="noreferrer" target="_blank">http://libvirt.org/firewall.<wbr>html</a>:<br>
>>><br>
>>>> type=nat<br>
>>>><br>
>>>> Allow inbound related to an established connection. Allow outbound, but<br>
>>>> only from our expected subnet. Allow traffic between guests. Deny<br>
>>>> all other<br>
><br>
> I would expect the 'traffic between guests' to mean only guests on the<br>
> same network.  Also that lines up with what's written above.<br>
<br>
</div></div>That is correct.<br>
<span class=""><br>
><br>
>>>> inbound. Deny all other outbound.<br>
>>><br>
><br>
> [...]<br>
><br>
>><br>
>> Thanks for reporting this.  It's clearly a bug in libvirt.  The rules<br>
>> are in this order:<br>
>><br>
>>  all rules for virbr0<br>
>>  all rules for virbr1<br>
>>  all rules for virbr2<br>
>><br>
>> But what we should do instead is:<br>
>><br>
>>  input rules for all networks<br>
>>  local rules for all networks<br>
>>  output rules for all networks<br>
>>  reject rules for all networks<br>
<br>
</span>That doesn't achieve the desired results (as you figured out later,<br>
according to your followup comments.<br>
<span class=""><br>
<br>
>><br>
>> The problem is that we do not know how other rules look like.  So what<br>
>> we might need to do is create chains where rules for the first network<br>
>> are, then only append network rules into those chains.<br>
>><br>
>> Would you mind filing a bug for this issue, so we can properly track it<br>
>> and don't forget about it?  I'll have a look at it in the meantime, but<br>
>> don't promise anything since I'm not that familiar with that part of the<br>
>> codebase.<br>
>><br>
><br>
> Actually, now that I'm thinking about it, the problem is not that we<br>
> disallow the communication from virbr1 to virbr0, but the problem is<br>
> that we allow the connection from virbr0 to everywhere.<br>
<br>
</span>Yep!<br>
<br>
That's actually a known bug that has been there "forever". It has always<br>
been brought up in the context of "I want communication between my NATed<br>
networks, and it only works in one direction!", rather than "I want to<br>
block communication between my NATed networks, but it gets past in one<br>
direction!". When people learn that it's (kind of) blocked, they work<br>
around it by adding a new network that is shared by all the guests.<br>
Because all of the reports have been in this direction, fixing it<br>
properly has been very low on (my) priority list.<br>
<span class=""><br>
<br>
><br>
> Maybe the solution would be: for each network, insert the rules on top<br>
> of the forward chain and for each started network, explicitly reject<br>
> that one.  So that after one network starts it would look like this (I'm<br>
> writing this from memory just to illustrate the idea, not actually<br>
> looking up how stuff looks):<br>
><br>
>  ACCEPT any virbr0 RELATED,ESTABLISHED<br>
>  ACCEPT virbr0 virbr0<br>
>  ACCEPT virbr0 any src:<a href="http://192.168.122.0/24" rel="noreferrer" target="_blank">192.168.122.0/24</a><br>
>  REJECT any virbr0<br>
>  REJECT virbr0 any<br>
><br>
> And after second network is started, we'd have:<br>
><br>
>  # This one is new:<br>
>  REJECT virbr1 virbr0<br>
<br>
</span>Yeah, it's (mostly) this rule that makes the solution complicated.<br>
Essentially you need one of these rules for each pair of virtual<br>
networks, so if you have 10 networks, you'll need 45 rules, for 11<br>
you'll need 55 (in general, for "n" networks, you'll need (n * (n-1) /<br>
2) extra rules).<br>
<br>
Aside from the extra packet processing overhead caused by the high<br>
number of rules needed (which may be completely insignificant), and the<br>
necessity to add/remove rules at specific labels rather than just<br>
inserting them all at the beginning, there is the issue that currently<br>
each iptables rule added for a libvirt network is dependent only on that<br>
network, so it's simple to determine which rules to remove when a<br>
network is destroyed. If we start adding rules that are dependent on two<br>
networks, then proper cleanup will be more complicated.<br>
<br>
None of that should prevent a properly motivated person from writing the<br>
code to do it, of course!<br>
<div class="HOEnZb"><div class="h5"><br>
>  # These ones would be normally at the end, IIRC:<br>
>  ACCEPT any virbr1 RELATED,ESTABLISHED<br>
>  ACCEPT virbr1 virbr1<br>
>  ACCEPT virbr1 any src:<a href="http://192.168.122.0/24" rel="noreferrer" target="_blank">192.168.122.0/24</a><br>
>  REJECT any virbr1<br>
>  REJECT virbr1 any<br>
>  # These are left as they were:<br>
>  ACCEPT any virbr0 RELATED,ESTABLISHED<br>
>  ACCEPT virbr0 virbr0<br>
>  ACCEPT virbr0 any src:<a href="http://192.168.122.0/24" rel="noreferrer" target="_blank">192.168.122.0/24</a><br>
>  REJECT any virbr0<br>
>  REJECT virbr0 any<br>
><br>
> Cc'ing Laine so that he can weigh in as he has way more knowledge of<br>
> this part of the code =)<br>
</div></div></blockquote></div><br></div>