Try this:
- Setup the virtualbox to use 2 adapters:
- The first adapter is set to NAT (that will give you the internet connection).
- The second adapter is set to host only.
- Start the virtual machine and assign a static IP for the second adapter in Ubuntu (for instance 192.168.56.56). The host Windows will have 192.168.56.1 as IP for the internal network (VirtualBox Host-Only Network is the name in network connections in Windows). What this will give you is being able to access the apache server on ubuntu, from windows, by going to 192.168.56.56. Also, Ubuntu will have internet access, since the first adapter (set to NAT) will take care of that.
- Now, to make the connection available both ways (accessing the windows host from the ubuntu guest) there's still one more step to be performed. Windows will automatically add the virtualbox host-only network to the list of public networks and that cannot be changed. This entails that the firewall will prevent proper access.
- To overcome this and not make any security breaches in your setup:
- go to the windows firewall section, in control panel,
- click on advanced settings. In the page that pops up,
- click on inbound rules (left column), then on new rule (right column). Chose custom rule, set the rule to allow all programs, and any protocol. For the scope, add in the first box (local IP addresses) 192.168.56.1, and in the second box (remote IP) 192.168.56.56. Click next, select allow the connection, next, check all profiles, next, give it a name and save.
That's it, now you have 2 way communication, with apache/any other service available as well as internet.
The final step is to setup a share. Do not use the shared folders feature in virtualbox, it's quite buggy especially with windows 7 (and 64 bit). Instead use samba shares - fast and efficient.
Follow this link for how to set that up: https://wiki.ubuntu.com/MountWindowsSharesPermanently
Docker by default does not allow traffic between any two of its containers that are connected to different bridges. And also it does not allow traffic from a container to a port that has been mapped to the outside by docker itself. This is all implemented with iptables.
First off, the mapping of a port to the outside also happens with iptables. It uses a DNAT
rule in the nat table. For these rules Docker creates a separate DOCKER
chain, so that the same rules apply from PREROUTING
or OUTPUT
in the nat table. The DNAT
rules are preceded with RETURN
jumps that filter out all traffic coming from a Docker bridge. So that is the first hurdle.
It looks a bit like this:
-A DOCKER -i br-one -j RETURN
-A DOCKER -i br-two -j RETURN
-A DOCKER ! -i br-one -p tcp -m tcp --dport EXPOSEDPORT -j DNAT --to-destination 172.17.0.2:INTERNALPORT
The DNAT
rule can also have a -d address
if you exposed the port to that local address only. No traffic from any Docker bridge can hit the DNAT
rule(s) because of the RETURN
rules before that. And also on top of that, the DNAT
rule does not allow a DNAT
back through the same bridge the traffic came from. Which wouldn't be necessary anyway, because from the same bridge you can just reach the INTERNALPORT already.
The restriction on traffic between containers on different bridges is implemented in the filter table of iptables. Two custom chains are at the beginning of the FORWARD
chain, and the default policy of that chain is DROP
. One is for containers with user-defined bridges, the other for containers with Docker bridges: DOCKER-ISOLATION-STAGE-1
. That chain again uses DOCKER-ISOLATION-STAGE-2
. The combination of both says basically that if traffic leaves a Docker bridge and then enters another Docker bridge, then DROP
it (without ICMP signaling, so the connection just hangs.....)
It looks like this:
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A DOCKER-ISOLATION-STAGE-1 -i br-one ! -o br-one -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-two ! -o br-two -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-2 -o br-one -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-two -j DROP
So, if you want traffic from bridge one, to hit a DNAT
for a port exposed on the outside by a container on bridge two and you want the traffic to return for a full connection, then you have to do a couple of things:
Drop the RETURN
rules that stops the traffic from DNAT
in the DOCKER
chain in the nat table. You HAVE to remove the RETURN
for the source bridge. You CAN leave the RETURN
for the destination bridge, if you don't want to allow a container from that bridge to access a DNAT
exposed port.
iptables -t nat -D DOCKER -i br-one -j RETURN
iptables -t nat -D DOCKER -i br-two -j RETURN
#Optional if br-one -> br-two
Remove the DROP
rules for both bridges from the DOCKER-ISOLATION-STAGE-2
chain in the filter table.
iptables -t filter -D DOCKER-ISOLATION-STAGE-2 -o br-one -j DROP
iptables -t filter -D DOCKER-ISOLATION-STAGE-2 -o br-two -j DROP
Now the lines are open.
Docker does not often refresh its rules (at least not in the 19.03 version I tested with). It seems it only rebuilds the rule sets when the docker daemon restarts, not when you stop or start or create a container. You could try to tack any changes to the service restart to keep them persistent.
Best Answer
First here's a possible solution that could either be set up on the router itself or on any machine you'd like monitored: https://superuser.com/questions/853077/iptables-duplicate-traffic-to-another-ip
If that's not possible for your use case, there's another option in the form of a switch that can be set up between your router and all the clients, the switch should support port mirroring. You'd then add another NIC to your ids/docker host which would receive all the traffic from the mirrored switch's "WAN" port, which can be passed through to your suricata container.