Controlling (firewall) trafic to docker/docker-compose network - networking

I'm running docker a machine that server various services. I want to control these services using iptables or preferably using ufw (as I'm not that skilled with iptables itself).
In my previous setup, I used "vanilla" docker which uses a virtual interface called "docker0" to route network traffic through containers. I successfully "googled" a solution to make the firewall work described in this article: https://svenv.nl/unixandlinux/dockerufw (note: even though I wrote the article, it's just a sum of internet knowledge merged together).
One of the things the I found was this piece:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
COMMIT
Which (I assume) makes sure everything goes into docker0 properly.
Now I've change my setup and started using "docker-compose" which spins up docker containers automatically in an isolated network. Once again, docker uses a virtual device for this which is named after the id of the network:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
(...)
207a57fc0080 dockeropenvpndata_network-vpn bridge local
(...)
and...
$ ifconfig | grep 207a57fc0080
br-207a57fc0080 Link encap:Ethernet HWaddr 02:42:ce:c5:81:04
I assume that changing the iptables config posted above to the new network device might solve the problem:
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING ! -o br-207a57fc0080 -s 172.17.0.0/16 -j MASQUERADE
COMMIT
However I have no idea how to test this.
The interface's name (network id) seems to be (pseudo) random
The interface's name (network id) is only known after docker-compose up
As far as I know the rule is applied at boot time, when the id is still unknown.
In short, I'm looking for a way to firewall my docker machine again. Does anyone know how to achieve this?

Turns out that the configuration in /etc/default/docker is not taken into account when using systemd, resulting in --iptables=false not being set.
The docker options for systemd are specified in the service file in /lib/systemd/system/docker.service. Entries in this file can be overridden by adding/adjusting the drop-in file in cat /etc/systemd/system/docker.service.d/docker.conf
I add the drop-in file with these contents:
[Service]
EnvironmentFile=-/etc/default/docker
ExecStart=
ExecStart=/usr/bin/dockerd --iptables=false -H fd://
(The first empty ExecStart= is actually required)
This starts docker without the iptables configuration and makes the original steps (see link in the original question) work again.

Related

Iptables meet with jupyter notebook

I met a interesting problem today...
First, I setup a iptable policy like this:
iptables -A INPUT -p tcp --dport <jupyter_server_port> -j ACCEPT
iptables -P INPUT DROP
that will drop all the packages except those TCP packages who request the jupyter server. After I did this, I could still get response from the server. But the notebook said it couldn't connect to the kernel.
After some googling, I found this document https://ipython.org/ipython-doc/3/development/how_ipython_works.html which indicate that the notebook server need to communicate to the ipython kernel through ZeroMQ. So, I disable the second policy and problem solved.
But I still wonder How I could still keeping the second policy and let the server work just like normal?

IP tables rules which allows only the communicate with IP which are assigned

I have ubuntu server with few vps running, mostly shared between friends and colleagues, it is from Hetzner,
I also have 2 set of ips ranging from 5.9.237.xxx to 5.9.237.xxx & 5.9.248.xxx to 5.9.248.xxx.
Today they locked my server due to different IP set on the VPS which is causing the problem, now i have KVM access, and they asked me to set up an IP TABLE rule which only allow to communicate the IP which are assigned and ignore the rest,
How to do this? Am a bit lost,
My OS is Ubuntu, and i want command that will ignore all the ips except the set of ip i give.
Thank You.
You need to drop all (careful with iptables, you can block yourself out) you should learn how your distro handles them .. here are the command s that after a reboot will reset back to normal so temp to test.. .
iptables -A INPUT -i eth0 -j DROP
iptables -I INPUT -i eth0 -s 10.10.10.0/24 -j ACCEPT
or of course specify certain ips
iptables -I INPUT -i eth0 -s 10.10.10.118 -j ACCEPT
there is alot more to iptables then this but this should get you started

Docker receiving multicast traffic

We have a dockerized server application that is doing auto-discovery of physical appliances on the network by listening for multicast packets on port 6969. So we need our docker container to be able to receive these packets from devices outside the host, through the host, and in to the container. I've seen some similar issues and done a lot of reading but I'm still unable to get the server to respond to these multicast packets.
I'm sitting on Wireshark watching network traffic, but I'm not a specialist. I know Docker creates a MASQUERADE address to make the traffic all look like it's coming from the Docker gateway, so when I watch veth I see mostly talk between 172.17.0.1 and 172.17.0.2 although my server is unable to retrieve any information about the devices on the network. (If I run outside of docker, I have no issues of course.)
I can't use --net=host as, like others, we make use of the --link feature. I've tried the following variations...
docker run --name app -p 6969:6969 -d me/app:latest
docker run --name app -p 0.0.0.0:6969:6969 -d me/app:latest (This one I could have sworn worked once but now doesn't?)
docker run --name app -p 0.0.0.0:6969:6969/udp -d me/app:latest
docker run --name app -p 255.255.255.255:6969:6969 -d me/app:latest
Any help or insight you could provide would be greatly appreciated.
Try to enable multicast on your nics:
ip link set eth0 multicast on
echo 1 >/proc/sys/net/ipv4/ip_forward to turn on IP forwarding
You need to explicitly set or at least check that it is enabled on relevant interfaces.
net.ipv4.conf.all.mc_forwarding = 1
net.ipv4.conf.eth0.rp_filter=0
Allow the multicast traffic:
iptables -I INPUT -d 224.0.0.0/4 -j ACCEPT
iptables -I FORWARD -d 224.0.0.0/4 -j ACCEPT
Also you might need to add the route for multicast traffic:
route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0
Change the TTL of the multicast sender:
iptables -t mangle -A OUTPUT -d <group> -j TTL --ttl-set 128
Where group is the multicast group address of the stream you want to change the TTL of.
Also you can start multicast proxy
PS:
You should try (if above doesn't help) to start docker container with --net=none option and use pipework with follow command:
pipework docker0 -i eth0 CONTAINER_ID IP_ADDRESS/IP_MASK#DEFAULT_ROUTE_IP
which creates eth0 interface inside container with IFF_MULTICAST flag and defined IP address.

Setting Up Docker Dnsmasq

I'm trying to set up a docker dnsmasq container so that I can have all my docker containers look up the domain names rather than having hard-coded IPs (if they are on the same host). This fixes an issue with the fact that one cannot alter the /etc/hosts file in docker containers, and this allows me to easily update all my containers in one go, by altering a single file that the dnsmasq container references.
It looks like someone has already done the hard work for me and created a dnsmasq container. Unfortunately, it is not "working" for me. I wrote a bash script to start the container as shown below:
name="dnsmasq_"
timenow=$(date +%s)
name="$name$timenow"
sudo docker run \
-v="$(pwd)/dnsmasq.hosts:/dnsmasq.hosts" \
--name=$name \
-p='127.0.0.1:53:5353/udp' \
-d sroegner/dnsmasq
Before running that, I created the dnsmasq.hosts directory and inserted a single file within it called hosts.txt with the following contents:
192.168.1.3 database.mydomain.com
Unfortunately whenever I try to ping that domain from within:
the host
The dnsmasq container
another container on the same host
I always receive the ping: unknown host error message.
I tried starting the dnsmasq container without daemon mode so I could debug its output, which is below:
dnsmasq: started, version 2.59 cachesize 150
dnsmasq: compile time options: IPv6 GNU-getopt DBus i18n DHCP TFTP conntrack IDN
dnsmasq: reading /etc/resolv.dnsmasq.conf
dnsmasq: using nameserver 8.8.8.8#53
dnsmasq: read /etc/hosts - 7 addresses
dnsmasq: read /dnsmasq.hosts//hosts.txt - 1 addresses
I am guessing that I have not specified the -p parameter correctly when starting the container. Can somebody tell me what it should be for other docker containers to lookup the DNS, or whether what I am trying to do is actually impossible?
The build script for the docker dnsmasq service needs to be changed in order to bind to your server's public IP, which in this case is 192.168.1.12 on my eth0 interface
#!/bin/bash
NIC="eth0"
name="dnsmasq_"
timenow=$(date +%s)
name="$name$timenow"
MY_IP=$(ifconfig $NIC | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}')
sudo docker run \
-v="$(pwd)/dnsmasq.hosts:/dnsmasq.hosts" \
--name=$name \
-p=$MY_IP:53:5353/udp \
-d sroegner/dnsmasq
On the host (in this case ubuntu 12), you need to update the resolv.conf or /etc/network/interfaces file so that you have registered your public IP (eth0 or eth1 device) as the nameserver.
You may want to set a secondary nameserver to be google for whenever the container is not running, by changing the line to be dns-nameservers xxx.xxx.xxx.xxx 8.8.8.8 E.g. there is no comma or another line.
You then need to restart your networking service sudo /etc/init.d/networking restart if you updated the /etc/network/interfaces file so that this auto updates the /etc/resolve.conf file that docker will copy to the container during the build.
Now restart all of your containers
sudo docker stop $CONTAINER_ID
sudo docker start $CONTAINER_ID
This causes their /etc/resolv.conf files update so they point to the new nameserver settings.
DNS lookups in all your docker containers (that you built since making the changes) should now work using your dnsmasq container!
As a side note, this means that docker containers on other hosts can also take advantage of your dnsmasq service on this host as long as their host's nameserver settings is set to using this server's public IP.

Write IPTable rules

How to write IPTable rules such that the administrator on 128.238.66.2 has ssh access to the firewall and no one else is allowed access?
Is it like: iptables –A INPUT –s 128.238.66.2 –j ACCEPT?
Try like this (please be aware that if the IP is wrong, you're locked out):
iptables -A INPUT -p tcp --dport ssh -j REJECT
iptables -A INPUT -p tcp -s 128.238.66.2 --dport ssh -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --sport ssh -m state --state ESTABLISHED -j ACCEPT
When we say about iptable it is that it bounds with Kernel. The function of iptable is for Setting_Up Firewall.
And to understand its basics you should understand it in, from ground level rather knocking with your sequence of absurd commands as you end-up scribbling & scratching head. Following step by step standard instruction will not be scenario always. SO, lets understand it.
There are three level segregation when we talk about iptable.
Level-1: Rule
Level-2: Chain
Level-3: Table
Lets see one by one now,
Rules are-> ACCEPT, DROP, QUEUE, RETURN
Chains are-> Input, Output, Forward, Pre Routing, Post Routing
Tables are-> Filter Table (Default), NAT Table, RAW Table, Mangle Table
Coming Next Firewalls by generations of improvement can be said like,
1) Packet Filtering Firewall
2) Stateful Firewall
3) Application Layer Firewall
4) Proxies Firewall.

Resources