Starting docker.service fails with "iptables: No chain/target/match by that name" - linux

I've just finished installing docker in a server with Centos, but failed to execute sudo service docker start. Executing sudo service docker restart and reboot the server doesn't help.
The report error by executing sudo dockerd:
Error creating default "bridge" network: Failed to program FILTER chain: iptables failed: iptables --wait -I FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT: iptables: No chain/target/match by that name.
(exit status 1)
It seems like docker0 cannot be found, so I have checked the iptables by ip a:
...
6: docker0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default
link/ether 02:42:81:95:ec:06 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
The docker0 exists but its state is DOWN, I don't know if it's the reason.
Some information about my docker (docker --version) and system environment (uname -a):
Docker version 19.03.4, build 9013bf583a
Linux xxxxxxxxxxxxx 4.19.91-009.ali4000.alios7.x86_64 #1 SMP Mon Jan 25 10:47:38 CST 2021 x86_64 x86_64 x86_64 GNU/Linux
Currently I don't know how to fix it.
Update
The result of executing sudo iptables -S is as follows:
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -j RETURN

Related

Docker container doesn't have any internet access

After working a long time on why i don't have any internet access into Docker i had to ask here, i read a lot of solutions which posted in this site, my problem don't resolve
what i did before asking here:
1:
pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
sudo service docker restart
2:
OTHER_BRIDGE=br-b0b70e352d8c
service docker stop
ip link set dev $OTHER_BRIDGE down
ip link set dev docker0 down
ip link delete $OTHER_BRIDGE type bridge
ip link delete docker0 type bridge
service docker start && service docker stop
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.18.0.0/16 -j MASQUERADE
service docker start
3: stopping iptables and docker daemon:
sudo service iptables stop
sudo service docker restart
4:forwarding rules in iptables:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
and then adding DNS into /etc/default/docker:
DOCKER_OPTS="--dns 208.67.222.222 --dns 208.67.220.220"
is another solution to fix this problem? i also tested internet access after rebooting system

Can't access any website when connected to pptp vpn

Server for test:
Server based in China can't access Gooogle,Facebook,Instagram,Twitter, but you can try to use it test connection to stackoverflow
ip: 132.232.70.189
account: yunaqi
password: qishi
What I did on my server:
install pptp
sudo yum -y install pptpd
edit sysctl.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward=1
edit pptpd.conf
vi /etc/pptpd.conf
localip 192.168.0.1
remoteip remoteip 192.168.0.234-238,192.168.0.245
edit chap-secrets
vi /etc/ppp/chap-secrets
yuanqi * qishi *
config iptables
sudo iptables -A INPUT -p gre -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 47 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.0.1/24 -o eth0 -j MASQUERADE
start pptp
systemctl enable pptpd.service
systemctl start pptpd.service
That's all, I don't kown which step is wrong.Please help me.

iptables script to block all internet access except for desired applications

CONTEXT:
I wanted to have a shell script that would block all Inbound/Outbound traffic to my computer, UNLESS I decide I want to use the browser or some other application, in which case I would summon it and only those applications would run.
I have researched previous scripts made by smart individuals (links to sources at the end), as well as invested the time to learn to use iptables myself (still working on this front).
Here is the result of the work done:
RESULTS:
before the shell script is run, a group called internet is created:
sudo groupadd internet
Shell Script:
#!/bin/sh
#only allow apps run from "internet" group to run
# clear previous rules
sudo iptables -F
# accept packets for internet group
sudo iptables -A OUTPUT -p tcp -m owner --gid-owner internet -j ACCEPT
sudo iptables -A OUTPUT -p udp -m owner --gid-owner internet -j ACCEPT
# also allow local connections
sudo iptables -A OUTPUT -p tcp -d 127.0.0.1 -j ACCEPT
sudo iptables -A OUTPUT -p tcp -d 192.168.0.1/24 -j ACCEPT
# reject packets for other users
sudo iptables -A OUTPUT -j REJECT
# same process for IPv6:
sudo ip6tables -A OUTPUT -p tcp -m owner --gid-owner internet -j ACCEPT
sudo ip6tables -A OUTPUT -p udp -m owner --gid-owner internet -j ACCEPT
sudo ip6tables -A OUTPUT -p tcp -d 127.0.0.1 -j ACCEPT
sudo ip6tables -A OUTPUT -p tcp -d 192.168.0.1/24 -j ACCEPT
sudo ip6tables -A OUTPUT -j REJECT
this is the other part of the shell that I'm currently working on and not 100% confident with:
#DROPS ALL INPUT and FORWARD
sudo iptables -A INPUT -j DROP
sudo iptables -A FORWARD -j DROP
#ONLY ACCEPTS INPUT THAT WAS INITIATED BY SOME OUTPUT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#SAME REPEATED FOR IPv6
sudo ip6tables -A INPUT -j DROP
sudo ip6tables -A FORWARD -j DROP
sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
after the whole script above is executed, the following command would open a terminal that would be part of the internet group, and hence any application (like firefox for instance) that were open by that terminal would have internet access, while all other INPUT/OUTPUT would be stopped
sudo -g internet -s
QUESTION:
Is the previous logic in order? Currently I am working on testing out all the features, by installing network monitoring software (nethogs), testing each line of code and seeing if the result is as expected, BUT at the same time, I only started learning about iptables 2 days ago, so even though the sources of the original code is done by experienced coders, I am not 100% confident in my ability to put it all together to produced the desired result. Thanks to anyone who took the time to read all this and participate in the discussion !!!
sources:
https://plus.google.com/+TobyKurien/posts/YZhZJCZmGgm
https://serverfault.com/questions/429400/iptables-rule-to-allow-all-outbound-locally-originating-traffic
P.S.: Thanks to #dirkt for previously helping me understand a lot of the fundamental concepts of iptables as well as answering some of my questions regarding the source code.
UPDATE:
So after having run the code, there seems to be something wrong. What happens is as follows. I run the shell script:
bash myscript
I get 2 errors as follows:
ip6tables v1.6.0: host/network 127.0.0.1 not found
Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables v1.6.0: host/network 198.168.0.1 not found
Try `ip6tables -h' or 'ip6tables --help' for more information.
but everything else ran well, and when doing sudo iptables -L I did confirm all the other rules are in place. AFTER that, I tried the following:
Run firefox by manually double-clicking the icon. The result was as expected, right away I got a Server not found error, which was a good sign
After that I ran the command sudo -g internet -s in the terminal, and then firefox. NOW... when I tried loading a website, it didn't show me Server not found, but it keep loading for a long period of time, very long. This leads me to believe that maybe the output response was sent, BUT the input was being blocked.
If anyone knows why this might be happening, I would love to know your feedback!
I only started learning about iptables 2 days ago, so even though the sources of the original code is done by experienced coders, I am not 100% confident in my ability to put it all together to produced the desired result.
Coincidentally, I'm looking for the same solution around the same time and saw your post. Just sign-up SO, hope this could help you and others. I'm still learning and open to suggestion and advice :)
A few change to the code. I need to open all port to local connections to make it work.
Also changed 192.168.0.1/24 to 192.168.0.0/16. This range allowed wifi/usb tether to be included.
# also allow local connections
#TODO. Use log to see which port are actually needed.
sudo iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
Is the previous logic in order?
Change the order for/to this code.
#ONLY ACCEPTS INPUT THAT WAS INITIATED BY SOME OUTPUT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#DROPS ALL INPUT and FORWARD
sudo iptables -A INPUT -j DROP
sudo iptables -A FORWARD -j DROP
Also add this code on top of previous code. These are taken from default firewall. Originally it contained specific interface.
sudo iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 67 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 67 -j ACCEPT
I get 2 errors as follows:
ip6tables v1.6.0: host/network 127.0.0.1 not found Try `ip6tables -h' or 'ip6tables --help' for more information.
ip6tables v1.6.0: host/network 198.168.0.1 not found Try `ip6tables -h' or 'ip6tables --help' for more information.
Probably because you are using IP4 address.
Change 127.0.0.1 to ::1/128 and 198.168.0.1 to fe80::/10.
Can't help much about IPv6. I have no idea how it work and I don't think mine using IPv6 at all.
Complete Script:
#!/bin/sh
#only allow apps run from "internet" group to run
# clear previous rules
sudo iptables -F
# accept packets for internet group
sudo iptables -A OUTPUT -p tcp -m owner --gid-owner internet -j ACCEPT
sudo iptables -A OUTPUT -p udp -m owner --gid-owner internet -j ACCEPT
#Some application need more port. Such as ping.
sudo iptables -A OUTPUT -p icmp -m owner --gid-owner internet -j ACCEPT
#Less secure. Open all port.
#sudo iptables -A OUTPUT -m owner --gid-owner internet -j ACCEPT
# also allow local connections
#TODO. Use log to see which port are actually needed.
sudo iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# reject packets for other users
sudo iptables -A OUTPUT -j REJECT
#Taken from default rules.
sudo iptables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp -m udp --dport 67 -j ACCEPT
sudo iptables -A INPUT -p tcp -m tcp --dport 67 -j ACCEPT
#ONLY ACCEPTS INPUT THAT WAS INITIATED BY SOME OUTPUT
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
#DROPS ALL INPUT and FORWARD
sudo iptables -A INPUT -j DROP
sudo iptables -A FORWARD -j DROP
#IPv6 Section
# Flush ip6tables too
sudo ip6tables -F
# same process for IPv6:
sudo ip6tables -A OUTPUT -p tcp -m owner --gid-owner internet -j ACCEPT
sudo ip6tables -A OUTPUT -p udp -m owner --gid-owner internet -j ACCEPT
sudo ip6tables -A OUTPUT -d ::1/128 -j ACCEPT
sudo ip6tables -A OUTPUT -d fe80::/10 -j ACCEPT
sudo ip6tables -A OUTPUT -j REJECT
sudo ip6tables -A INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo ip6tables -A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
sudo ip6tables -A INPUT -p udp -m udp --dport 67 -j ACCEPT
sudo ip6tables -A INPUT -p tcp -m tcp --dport 67 -j ACCEPT
sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo ip6tables -A INPUT -j DROP
sudo ip6tables -A FORWARD -j DROP

Attempting to setup static IP block with ATT Uverse and IP Passthrough to ASUS router

I am trying to accomplish the following setup:
NVG599 <> ASUS RT-AC88U <> Static device
I have an Ubuntu Server running Apache which has been configured to use an internal address 192.x.x.x as well as one of the static IP addresses. I know Apache is running / listening / working. If I browse to the internal address I get the default Apache page. Ubuntu firewall is disabled. I actually have a domain setup that points to this IP address 'http://thelavender.net'
Normally the ATT RG would handle the second subnet / static IP block. What I cannot figure out is how the ASUS would handle these now that its basically taking over all routing duties.
There is a cascading router option in the ATT RG and I have seen some people talking about using this instead. Is this correct?
EDIT
Thinking back, I think 1:1 NAT is what I really need here correct?
EDIT 2
I tried using something along the lines of this:
#!/bin/sh
#
# to restore this configuration, it needs to be saved to /jffs/scripts/nat-start
# on the router.
#
ifconfig eth0:0 WanIP1 netmask 255.255.255.248 up
iptables -t nat -A PREROUTING -i eth0 -d WanIP1 -j DNAT --to-destination 192.168.1.10
iptables -t nat -I POSTROUTING -s 192.168.1.10 -j SNAT --to WanIP1
#
ifconfig eth0:1 WanIP2 netmask 255.255.255.248 up
iptables -t nat -A PREROUTING -i eth0 -d WanIP2 -j DNAT --to-destination 192.168.1.11
iptables -t nat -I POSTROUTING -s 192.168.1.11 -j SNAT --to WanIP2
#
ifconfig eth0:2 WanIP3 netmask 255.255.255.248 up
iptables -t nat -A PREROUTING -i eth0 -d WanIP3 -j DNAT --to-destination 192.168.1.12
iptables -t nat -I POSTROUTING -s 192.168.1.12 -j SNAT --to WanIP3
#
# Port forwards, in case the webui doesn't work, but i think it will. uncomment below if needed.
# iptables -A FORWARD -p tcp --dport 80 -d 192.168.1.10 -j ACCEPT
I only tried the first group and put this in the nat-start script for Merlin to pick up. When I did this and restarted the router, it refused to pick up the WAN IP from the RG.
Any help with this would be appreciated.
EDIT
Voted down but no explanation as to why.
NVG599 LAN address: 192.168.0.254 / 255.255.255.0
RT-AC88U WAN address: 192.168.0.1 / 255.255.255.0
RT-AC88U LAN address: 192.168.1.1 / 255.255.255.0
NVG599 Cascaded Router: Enabled
Cascaded Router Address: 192.168.0.1
Network Address: 107.218.164.224
Subnet Mask: 255.255.255.248
Server: 192.168.1.10 and 107.218.164.225
Startup script for the router:
#!/bin/sh
#
# tell it where to find the server
ip ro add 107.218.164.225/32 via 192.168.1.10
iptables -I POSTROUTING -t nat -s 107.218.164.225/32 -j RETURN
#
# servers 2-N go here
......
#
# catch-all for everything else on the LAN
#
# this will double-NAT everything and will end up using the NVG's dynamic IP which is outside of the static IP block
##iptables -A POSTROUTING -t nat -o eth0 -j SNAT --to 192.168.0.1
#
# this uses one of the public IPs
iptables -A POSTROUTING -t nat -o eth0 -j SNAT --to 107.218.164.230
And script for the server if need be
#!/bin/sh
#
ifconfig eth0:1 107.218.164.225/29
ip ro repl default via 192.168.1.1 src 107.218.164.225

How do I configure Docker to work with my ens34 network interface (instead of eth0)?

does anyone know how docker decides which NIC will work with the docker0 network? I have a node with two interfaces (eth0 and ens34), however, only the requests that go through eth0 are forwarded to the container.
When my VM was provisioned and Docker was installed, I started a very silly test: I created a centos vm, installed netcat on it and committed the image. Then I started a daemon container listening on port 8080. I used:
docker -it -p 8080:8080 --name nc-server nc-server nc -vv -l 8080
So I tried to connect to the container listening on port 8080 from another node in the same network (in the same IP address as the interface ens34). It did not work.
Whereas when I sent a request from another machine to the IP address from eth0, I saw some reaction in the container (the communication worked). I was "tailing" its output with:
docker logs -ft nc-server
My conclusion with this experiment: there's some mysterious relationship between eth0 (primary NIC) and docker0, and the requests that are sent to ens34 (10.) interface are never forwarded to the veth / docker0 interfaces, only the requests that go through eth0 (9.*). Why's that?
Also, I know I can make everything work if I use --net=host, but I don't want to use that... it doesn't feel right somehow, is it a standard practice to use the HOST mode in Docker containers? Any caveats on that?
--
UPDATE:
I managed to make it work after disabling iptables:
service iptables stop
However, I still don't get what is going on. The info below should be relevant to understand what is going on:
ifconfig
[root#mydockervm2 myuser]# ifconfig | grep -A 1 flags
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
--
ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.1.21.18 netmask 255.255.255.0 broadcast 10.1.21.255
--
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 9.32.145.99 netmask 255.255.255.0 broadcast 9.32.148.255
--
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
--
veth8dbab2f: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::3815:67ff:fe9b:88e9 prefixlen 64 scopeid 0x20<link>
--
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
netstat
[root#mydockervm2 myuser]# netstat -nr
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
0.0.0.0 9.32.145.1 0.0.0.0 UG 0 0 0 eth0
9.32.145.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
10.1.21.0 0.0.0.0 255.255.255.0 U 0 0 0 ens34
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 ens34
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
filters
[root#mydockervm2 myuser]# iptables -t filter -vS
-P INPUT ACCEPT -c 169 106311
-P FORWARD ACCEPT -c 0 0
-P OUTPUT ACCEPT -c 110 13426
-N DOCKER
-N DOCKER-ISOLATION
-A FORWARD -c 0 0 -j DOCKER-ISOLATION
-A FORWARD -o docker0 -c 0 0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -c 0 0 -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -c 0 0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -c 0 0 -j ACCEPT
-A FORWARD -m physdev --physdev-is-bridged -c 0 0 -j ACCEPT
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8080 -c 0 0 -j ACCEPT
-A DOCKER-ISOLATION -c 0 0 -j RETURN
nat
[root#mydockervm2 myuser]# iptables -t nat -vS
-P PREROUTING ACCEPT -c 28 4818
-P INPUT ACCEPT -c 28 4818
-P OUTPUT ACCEPT -c 8 572
-P POSTROUTING ACCEPT -c 8 572
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -c 2 98 -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -c 0 0 -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -c 0 0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 8080 -c 0 0 -j MASQUERADE
-A DOCKER -i docker0 -c 0 0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 8080 -c 0 0 -j DNAT --to-destination 172.17.0.2:8080
Thoughts?
First, rule out the obvious and make sure that hosts on the other networks know how to route to your machine to reach the container network. For that, check
netstat -nr
on the source host and make sure that your docker subnet is listed with your docker host as the gateway, or that the default router handling the traffic upstream knows about your host.
If traffic is getting routed but blocked, then you're getting into forwarding and iptables. For forwarding, the following should show a 1:
cat /proc/sys/net/ipv4/ip_forward
Make sure your local host shows a route for the bridges to your container networks with the same netstat command, there should be a line for the docker0 interface and your docker subnet as the destination:
netstat -nr
For iptables, check to see if there are any interface specific nat or filter rules that need to be adjusted:
iptables -t filter -vS
iptables -t nat -vS
If your forward rule defaults to DROP instead of ACCEPT, you may want to add some logging, or just change the default to accept traffic if you believe it can be trusted (e.g. the host is behind another firewall).
This all being said, advertising ports directly on the host is a fairly common practice with containers. For the private stuff, you can setup multiple containers isolated on their internal network that can talk to each other, but no other containers, and you only expose the ports that are truly open to the rest of the world on the host with the -p flag to the run (or ports option in docker-compose).

Resources