1

I have a apache webserver running on ubuntu 18.04 hosted on KVM This KVM is running on Linux Mint 20.1 host OS

The networking is setup using bridge in KVM

<network connections="1">
  <name>host-bridge</name>
  <uuid>some-uuid</uuid>
  <forward mode="bridge"/>
  <bridge name="br0"/>
</network>

I have firewall rules to pass traffic from the real network to the bridge

sudo iptables -I INPUT 1 -i lo -j ACCEPT
#Pass to KVM Bridge
sudo iptables -t nat -A POSTROUTING -o br0 -j MASQUERADE
sudo iptables -A FORWARD -i br0 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i virbr0 -o br0 -j ACCEPT
sudo iptables -I FORWARD -i br0 -o br0 -j ACCEPT

This is all working I am getting traffic to the host and routed to the kvm machine, external ips can connect and so can internal

Unfortunately I also have some custom html that changes behaviour through php based on whether the referrer is on the local lan or a remote ip

Since migrating to KVM from VmWare now everything comes up as sourced from the host ip address and this logic doesn't work

Is there a way to maintain the request ip address so i can keep the same behaviour?

I check ips in php with

function getUserIpAddress()
   {
    $ip = getenv('HTTP_CLIENT_IP')?:
      getenv('HTTP_X_FORWARDED_FOR')?:
      getenv('HTTP_X_FORWARDED')?:
      getenv('HTTP_FORWARDED_FOR')?:
      getenv('HTTP_FORWARDED')?:
      getenv('REMOTE_ADDR');

      return $ip;
   }

And I've tried outputing all the above and they all show up as the host linux mint machines local lan IP

duindain
  • 111
  • 2
  • What are all the iptables rules for? – Michael Hampton Mar 14 '21 at 03:21
  • Without them the packets dont get to the KVM vm or out of it – duindain Mar 14 '21 at 04:04
  • 1
    That's odd. Did you block them somewhere else? You should not need any of those rules at all. And the masquerade rule is the one causing the problem. – Michael Hampton Mar 14 '21 at 05:25
  • I have a complex network setup including docker, multiple port forwarding and the default last rule is to drop anything not catered for in the previous rules Looks like removing -j MASQUERADE but leaving everything else has worked can you post your response as an answer and I'll mark it correct with my notes :) ty – duindain Mar 15 '21 at 12:56

1 Answers1

0

Removing -j MASQUERADE resolved the issue

without having to open the box up to be unfirewalled

I have the last firewall rule as

-A INPUT -j DROP

So anything not previously handled is dropped as this is a production machine with multiple ports exposed to the internet

A brief snapshot of my current working rules is

    -A INPUT -i lo -j ACCEPT
    -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
     #Just one example rule
    -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
    -A INPUT -p udp -m udp --dport 443 -j ACCEPT
    -A INPUT -j DROP
    -A FORWARD -i br0 -o br0 -j ACCEPT
    -A FORWARD -i br0 -o virbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT
    -A FORWARD -i virbr0 -o br0 -j ACCEPT
    -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

This drops all packets I don't explicitly add keeping the VM relatively safe network wise and I can again get the external IP now in php correctly

Although I suspect this is still perhaps wrong and it may be routing all traffic through the bridge before hitting my main pc so I've inserted the docker container as a go between as the ports I have listed are generally all for my main pc and not the VM, regardless its working well enough for now

Thanks for your help

duindain
  • 111
  • 2