linux bridge not work when attach more than one interface - kubernetes

this question is continuation of this problem packets lost after postrouting snat
if i create a linux bridge by command,the bridge can work normally,but if i create bridge by code,the bridge not work, a lot of strange behavior occurs。 This problem can be reproduced from other linux machines
my script for create docker container attached to bridge:
new_sandbox.sh
#!/usr/bin/env bash
set -euo pipefail
container_name=$1
container_ip=$2
br_name=$3
gw_ip=$4
echo "ready to create container $container_name connect to br $br_name with ip $container_ip, gw $gw_ip"
docker run -d --network none --name $container_name schecter/test:v4
container_id=$(docker ps | grep $container_name | awk '{print $1}')
pid=$(docker inspect -f '{{.State.Pid}}' ${container_id})
ln -sfT /proc/$pid/ns/net /var/run/netns/${container_id}
echo "container_id=$container_id, pid=$pid"
host_veth="veth_"$pid"_0"
container_veth="veth_"$pid"_1"
ip link add dev $host_veth type veth peer name $container_veth
ip link set dev $host_veth master $br_name
ip link set dev $host_veth up
ip link set dev $container_veth netns ${container_id}
ip netns exec ${container_id} ip link set dev $container_veth up
ip netns exec ${container_id} ip address add $container_ip dev $container_veth
ip netns exec ${container_id} ip route add default via $gw_ip
my code for create bridge: br_init.go
package main
import (
"fmt"
"github.com/vishvananda/netlink"
"net"
)
var (
gwIp = "10.10.10.1/24"
bridgeName = "br1"
)
func main() {
br := &netlink.Bridge{
LinkAttrs: netlink.LinkAttrs{
Name: bridgeName,
MTU: 1500,
TxQLen: -1,
},
}
if err := netlink.LinkAdd(br); err != nil {
panic(err)
}
bridgeIf, err := netlink.LinkByName(bridgeName)
if err != nil {
panic(err)
}
err = netlink.LinkSetUp(bridgeIf)
if err != nil {
panic(err)
}
if err = netlink.SetPromiscOn(bridgeIf); err != nil {
panic(err)
}
gwip, gwnet, err := net.ParseCIDR(gwIp)
if err != nil {
panic(err)
}
gwnet.IP = gwip
addr := &netlink.Addr{IPNet: gwnet}
if err = netlink.AddrAdd(bridgeIf, addr); err != nil {
panic(err)
}
//// this line of code work fine
//exec.Command(fmt.Sprintf("ip link set br1 address %s", bridgeIf.Attrs().HardwareAddr))
//This line of code causes problems
if err = netlink.LinkSetHardwareAddr(bridgeIf, bridgeIf.Attrs().HardwareAddr); err != nil {
panic(err)
}
fmt.Println("success!!!!")
}
go version: 1.17,go.mod
module test
go 1.17
require github.com/vishvananda/netlink v1.2.1-beta.2
require (
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
golang.org/x/sys v0.4.0 // indirect
)
my command for create bridge: br_init.sh
#!/usr/bin/env bash
set -euo pipefail
ip link add dev br2 type bridge
ip address add 10.10.11.1/24 dev br2
ip link set br2 promisc on
ip link set br2 up
ip link set br2 address ca:b6:90:1d:8f:cf
then i create two bridge for compare. one created by code, one create by command, and attache two container to each bridge。
go run br_init.go
./new_sandbox.sh wjj_test1 10.10.10.3/24 br1 10.10.10.1
./new_sandbox.sh wjj_test2 10.10.10.4/24 br1 10.10.10.1
./br_init.sh
./new_sandbox.sh wjj_test3 10.10.11.3/24 br2 10.10.11.1
./new_sandbox.sh wjj_test4 10.10.11.4/24 br2 10.10.11.1
we can see two bridge,br1 created by code, br2 created by command:
root#n225-066-136:~/test# ip l
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether fa:16:3e:2e:a0:69 brd ff:ff:ff:ff:ff:ff
808: br1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/ether 36:84:ee:c7:e1:d1 brd ff:ff:ff:ff:ff:ff
809: br2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether ca:b6:90:1d:8f:cf brd ff:ff:ff:ff:ff:ff
811: veth_1557963_0#if810: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br1 state UP mode DEFAULT group default qlen 1000
link/ether 76:82:f0:5b:0f:83 brd ff:ff:ff:ff:ff:ff link-netns 00feea33629f
813: veth_1558110_0#if812: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br1 state UP mode DEFAULT group default qlen 1000
link/ether 3e:d8:af:b0:35:68 brd ff:ff:ff:ff:ff:ff link-netns 99bff89a3221
815: veth_1558312_0#if814: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br2 state UP mode DEFAULT group default qlen 1000
link/ether 16:69:e3:4a:6c:dc brd ff:ff:ff:ff:ff:ff link-netns 68eab047136b
817: veth_1558482_0#if816: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br2 state UP mode DEFAULT group default qlen 1000
link/ether 4e:43:fa:0c:83:8f brd ff:ff:ff:ff:ff:ff link-netns c2cabb285996
then config iptables:
iptables --table filter --append FORWARD --in-interface br1 --jump ACCEPT
iptables --table filter --append FORWARD --out-interface br1 --jump ACCEPT
iptables --table filter --append FORWARD --in-interface br2 --jump ACCEPT
iptables --table filter --append FORWARD --out-interface br2 --jump ACCEPT
iptables --table nat --append POSTROUTING --source 10.10.10.0/24 --jump MASQUERADE
iptables --table nat --append POSTROUTING --source 10.10.11.0/24 --jump MASQUERADE
container wjj_test1、wjj_test2 attached to br1, wjj_test3、wjj_test4 attached to br2。in wjj_test1, ping 8.8.8.8 failed。in wjj_test3, ping 8.8.8.8 success。
for br1, if only one container attached to it, the container can work fine, ping 8.8.8.8, if attached another contaoner to br1, the previous container immediately failed to ping。
As the comments show, I basically located the problematic code is
if err = netlink.LinkSetHardwareAddr(bridgeIf, bridgeIf.Attrs().HardwareAddr); err != nil {
panic(err)
}
if i remove this line, the bridge can work fine.(but we need to fix bridge's mac, otherwise it will change)
if i repalce this line to
exec.Command(fmt.Sprintf("ip link set br1 address %s", bridgeIf.Attrs().HardwareAddr))
the bridge can work fine。so it seem netlink.LinkSetHardwareAddr not equal to ip link set $link address $hwaddr。There are many unknown side effects
why the code can't work

Related

nftables don´t allow ssh

I have a ruleset in my server looking like this:
table inet firewall {
chain INBOUND {
type filter hook input priority filter; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" counter packets 0 bytes 0 accept
ip protocol icmp limit rate 4/second accept
ip6 nexthdr ipv6-icmp limit rate 4/second accept
ip protocol igmp limit rate 4/second accept
tcp dport 22 accept
log
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
}
chain OUTBOUND {
type filter hook output priority filter; policy drop;
oif "lo" counter packets 35 bytes 1946 accept
tcp dport 22 accept
}
}
I´m not be able to connect from ssh on port 22 even although should be opened. If I type:
$ nft flush ruleset, then, 22 port allows connection.
What I´m doing wrong?
It seems to me that the rules in the "OUTBOUND" chain are the problem.
You have tcp dport 22 accept but I think that should be tcp sport 22 accept because when the SSH packets are outbound from your server they will have a source port of 22, not a destination port of 22.
Change your OUTBOUND chain to:
chain OUTBOUND {
type filter hook output priority filter; policy drop;
# Allow traffic from established and related packets, drop invalid
ct state vmap { established : accept, related : accept, invalid : drop }
# Allow loopback
oif "lo" accept
# Accepted ports out (DNS / DHCP / TIME / WEB for package updates / SMTP)
ct state new udp dport { 53, 67, 123, 547 } accept
ct state new tcp dport { 53, 80, 443, 587 } accept
log prefix "DROP_output: " limit rate 3/second
}
Not accepting related outbound connections stopped sshd from responding.
Always log dropped packets at the end of every default deny chain. Often when something is not working it is a firewall issue.

Confuse about fail2ban behavior with firewallD in Centos 7

I was using fail2ban/iptables in a Centos 6 server.
I moved to Centos 7 and now I am using fail2ban/firewallD (installed by Webmin/Virtualmin with their defaults)
These are cat /var/log/maillog | grep "disconnect from unknown" screen shots
cat /var/log/fail2ban.log | grep Ban only displays
2019-10-27 16:52:22,975 fail2ban.actions [8792]: NOTICE [proftpd] Ban 111.225.204.32
Furthermore tailf /var/log/fail2ban.log displays several "already banned" of the same IP. In this case fail2ban, after maxretry is reached it tries to ban the IP.
Here are my configurations (partial), I left them as they were by defaults but changed bantimes.
jail.local
[postfix]
enabled = true
port = smtp,465,submission
bantime = -1
[postfix-sasl]
enabled = true
port = smtp,465,submission,imap3,imaps,pop3,pop3s
bantime = -1
[dovecot]
enabled = true
port = pop3,pop3s,imap,imaps,submission,465,sieve
bantime = -1
jail.conf
[DEFAULT]
findtime = 600
maxretry = 5
backend = auto
filter = %(__name__)s
port = 0:65535
banaction = iptables-multiport
banaction_allports = iptables-allports
action_ = %(banaction)s[name=%(__name__)s, bantime="%(bantime)s", port="% > (port)s", protocol="%(protocol)s", chain="%(chain)s"]
action = %(action_)s
jail.d/00-firewalld.conf
[DEFAULT]
banaction = firewallcmd-ipset
These files exist: action.d/firewallcmd-ipset.conf and filter.d/postfix.conf
firewall-cmd --direct --get-all-rules
ipv4 filter INPUT_direct 0 -p tcp -m multiport --dports ssh -m set
--match-set fail2ban-default src -j REJECT --reject-with icmp-port-unreachable
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable
ipv4 filter INPUT 0 -p tcp -m multiport --dports 10000 -m set --match-set fail2ban-webmin-auth src -j REJECT --reject-with icmp-port-unreachable
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh,sftp -m set --match-set fail2ban-ssh-ddos src -j REJECT --reject-with icmp-port-unreachable
After manually running
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='193.56.28.0/24' reject"
and
firewall-cmd --reload this output of tailf /var/log/fail2ban.log
stopped.
How can I get all those IPs banned after they reach maxretry value?
Would they be banned forever despite service restart or reload?
Edit 1:
From fail2ban.log with action=firewalld-cmd ipset
From fail2ban.log with action=iptables-allports
Edit 2:
It seems (I guess) something is flushing configurations (I guess it would be Webmin) because after a while I start getting error logs like failed to execute ban jail 'dovecot' action iptables-allports so I am trying this:
in actions.d created banning.conf
[Definition]
actionban = /usr/bin/firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='<IP>' reject"; ; /usr/bin/firewall-cmd --reload
and at jail.local
[DEFAULT]
banaction = iptables-multiport
banning
But I get Error in action definition banning
I know this is not a solution.
Before moving the server I was using fail2ban/iptables (not firewalld) for years not having to pay attention beyond default settings.
How can I get all those IPs banned after they reach maxretry value?
Your issue has probably nothing with maxretry etc.
If you see [jail] Ban 192.0.2.1 and several [jail] 192.0.2.1 already banned messages hereafter (especially after some minutes after the "Ban" message for same Jail/IP), this means only that your banning action (firewalld) does not work at all (after ban, the intruder-IP is still able to repeat its attempts).
In the last time we had certain issues with that (especially with combination firewalld + CentOS) - see for example https://github.com/fail2ban/fail2ban/issues/1609 as well as related firewalld issue - https://github.com/firewalld/firewalld/issues/515.
So check your native net-filter (iptables, etc), if you see some (white-listing established traffic) rules before fail2ban chains, it looks like your configuration is not fail2ban (or whatever banning-system) capable... here may be the answer for you - https://github.com/fail2ban/fail2ban/issues/2503#issuecomment-533105500.
Here is another similar issue with an example excerpt illustrating "wrong iptables rule that bypass fail2ban" - https://github.com/fail2ban/fail2ban/issues/2545#issuecomment-543347684
In this case:
either switch the backend of firewalld (as suggested above);
or switch the banaction of fail2ban to something native (iptables/ipset/etc).
or even add still one action dropping or killing active established connection of the banned IP (using something like tcpkill, killcx, ss etc).
UPDATE 1
jail.local example:
[DEFAULT]
banaction = iptables-multiport
banaction_allports = iptables-allports
[postfix-sasl]
enabled = true
[dovecot]
enabled = true
...
If after fail2ban reload you'd still see some IP making attempts after ban and already banned in fail2ban.log, provide log-excerpt of fail2ban by the first ban or else some possible errors around (because already banned is too late and does not help at all).
If no errors are there, provide output of iptables -nL.

Unable to to connect remotely to mongodb

Currently I am having trouble remote connecting a mongodb server on my virtual Ubuntu machine. I am unable to connect to with with Robomongo client that is running on my Windows PC that is also running the vm.
Here are the IP Addressees for both pcs
Windows:
Ethernet adapter Ethernet:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 192.168.1.137
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.1.1
Ubuntu:
enp0s3 Link encap:Ethernet HWaddr 08:00:27:6c:fc:9c
inet addr:192.168.1.134 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::9785:55d7:130:6618/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:5021 errors:0 dropped:0 overruns:0 frame:0
TX packets:465 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1231057 (1.2 MB) TX bytes:45237 (45.2 KB)
The error that I am getting on windows that show it can't connect:
Netstat that shows mongo is running:
netstat -tulpn | grep 27017
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 3611/mongod
From this point I tried to connect locally to the server and it works:
mongo --port 27017
MongoDB shell version: 2.6.10
connecting to: 127.0.0.1:27017/test
Then I tried to add port 27017 to the ufw and still unable to connect:
sudo ufw status
To Action From
-- ------ ----
27017 ALLOW Anywhere
27017 (v6) ALLOW Anywhere (v6)
Thanks for the help in advance.
Found the problem. It was due to the bind_ip flag in my mongodb.conf being set to 127.0.0.1. This is why I as only able to connect locally to the mongodb server.
Resolution was to comment out the bind_ip flag so it would not white list the IP Addresses.
Mongodb.conf
# mongodb.conf
# Where to store the data.
dbpath=/home/<username>/mongodb
#where to log
logpath=/home/<username>/mongodb/logs/mongodb.log
logappend=true
#bind_ip = 127.0.0.1
port = 27017
# Enable journaling, http://www.mongodb.org/display/DOCS/Journaling
journal=true
# Enables periodic logging of CPU utilization and I/O wait
#cpu = true
# Turn on/off security. Off is currently the default
#noauth = true
#auth = true
# Verbose logging output.
#verbose = true
# Inspect all client data for validity on receipt (useful for
# developing drivers)
#objcheck = true
# Enable db quota management
#quota = true
# Set oplogging level where n is
# 0=off (default)
# 1=W
# 2=R
# 3=both
# 7=W+some reads
#oplog = 0
# Diagnostic/debugging option
#nocursors = true
# Ignore query hints
#nohints = true
# Disable the HTTP interface (Defaults to localhost:27018).
#nohttpinterface = true
# Turns off server-side scripting. This will result in greatly limited
# functionality
#noscripting = true
# Turns off table scans. Any query that would do a table scan fails.
#notablescan = true
# Disable data file preallocation.
#noprealloc = true
# Specify .ns file size for new databases.
# nssize = <size>
# Accout token for Mongo monitoring server.
#mms-token = <token>
# Server name for Mongo monitoring server.
#mms-name = <server-name>
# Ping interval for Mongo monitoring server.
#mms-interval = <seconds>
# Replication Options
# in replicated mongo databases, specify here whether this is a slave or master
#slave = true
#source = master.example.com
# Slave only: specify a single database to replicate
#only = master.example.com
# or
#master = true
#source = slave.example.com
# Address of a server to pair with.
#pairwith = <server:port>
# Address of arbiter server.
#arbiter = <server:port>
# Automatically resync if slave data is stale
#autoresync
# Custom size for replication operation log.
#oplogSize = <MB>
# Size limit for in-memory storage of op ids.
#opIdMem = <bytes>
# SSL options
# Enable SSL on normal ports
#sslOnNormalPorts = true
# SSL Key file and password
#sslPEMKeyFile = /etc/ssl/mongodb.pem
#sslPEMKeyPassword = pass

HAproxy not routing from virtual IP

I am currently trying to configure HAProxy to route between two servers using a virtual IP.
For testing I created two instances, 172.16.4.130 and 172.16.4.131. I am then creating a virtual IP address of 172.16.4.99, using keepalived which will be bridging the two servers. Both of these servers are running apache2, which is hosting a simple index.html landing page for testing. All of the above is running.
When I go to 172.16.4.99, the page does not load, nor am I redirected to either one of the index.html pages. I can however, ping this IP address. I feel like this is a simple configuration issue, and since I am not very experienced with HAproxy, I would like some assistance. Below are my haproxy.cfg files, as well as keepalived.
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 4096
#debug
#quiet
user haproxy
group haproxy
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen webfarm 172.16.4.99:80
mode http
stats enable
stats auth user:password
balance roundrobin
cookie JSESSIONID prefix
option httpclose
option forwardfor
option httpchk HEAD /check.txt HTTP/1.0
server webA 172.16.4.130:8080 cookie A check
server webB 172.16.4.131:8080 cookie B check
keepalived.conf on 172.16.4.130
vrrp_script chk_haproxy { # Requires keepalived-1.1.13
script "killall -0 haproxy" # cheaper than pidof
interval 2 # check every 2 seconds
weight 2 # add 2 points of prio if OK
}
vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 51
priority 101 # 101 on master, 100 on backup
virtual_ipaddress {
172.16.4.99
}
track_script {
chk_haproxy
}
}
keepalived.conf on 172.16.4.131:
vrrp_script chk_haproxy { # Requires keepalived-1.1.13
script "killall -0 haproxy" # cheaper than pidof
interval 2 # check every 2 seconds
weight 2 # add 2 points of prio if OK
}
vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 51
priority 100 # 101 on master, 100 on backup
virtual_ipaddress {
172.16.4.99
}
track_script {
chk_haproxy
}
}
I have made similar structure to balancing transactions for the MYSQL. I can reach the MYSQL server behind virtual IP. Maybe my config helps you.
https://serverfault.com/questions/857241/haproxy-dont-balancing-requests-between-nodes-of-galera-cluster
It would be greate if it helps you.

TCL script cannot configure multicast socket

I'm working with tcl script under ubuntu 12.04, and I'm facing some problem when I try to configure a multicast socket. What I'm trying to do is to forward traffic from some socket to a multicast one, but I don't know why although the multicast socket is created well,apparently; it isn't bound to the multicast group I want to.
This is the script I'm using
#!/bin/sh
# test.tcl \
exec tclsh "$0" ${1+"$#"}
package require udp
set multicastPort "50003"
proc connector {unicastIP multicastIP port {protocol tcp}} {
if { [string equal $protocol "tcp"] } {
socket -server serverTCP -myaddr $unicastIP $port
puts "tcp"
} elseif {[string equal $protocol "udp" ] } {
serverUDP $unicastIP $multicastIP $port
puts "udp"
}
}
proc serverUDP {unicastIP multicastIP port} {
global multicastPort
set socketUDP [udp_open $port]
puts " $unicastIP"
fconfigure $socketUDP -blocking false -translation binary -buffering none -remote [list $unicastIP $port]
#fileevent $socketUDP readable [list gettingData $socketUDP]
set multicastSocket [udp_open $multicastPort]
udp_conf $multicastSocket -ttl 4
fconfigure $multicastSocket -blocking false -translation binary -buffering none -mcastadd $multicastIP -remote [list $multicastIP $port]
fileevent $socketUDP readable [list forwarding $socketUDP $multicastSocket ]
#puts $socketUDP "hello!"
#flush $socketUDP
}
proc forwarding {socketSrc socketDst} {
set data [read -nonewline $socketSrc]
puts "Read data-> $data"
puts -nonewline $socketDst $data
puts "Written data-> [read -nonewline $socketDst]"
}
connector 127.0.0.1 224.0.1.1 50000 udp
vwait forever
However if I run the script and check out the ports in my system, the multicast port is not assigned the proper multicast IP as you can see
~$ netstat -ptnlu
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:50000 0.0.0.0:* 3334/tclsh
udp 0 0 0.0.0.0:50003 0.0.0.0:* 3334/tclsh
Could anyone tell me the reason?
THanks in advance,
Regards!
AFAIK, that is OK. I have a multicast daemon in production using Tcl and its udp package, and netstat and ss tools also show me the socket as listening on the wildcard address.
"The trick" here, I suppose, is that multicasting is one level up the stack: joining a multicast group is not merely opening a socket or an endpoint on the group address but rather sending a very real IGMP "join" message to the local transport segment (Ethernet, in most deployments) and further communicating with the nearby IGMP routers (again, on Ethernet, they're mostly switches).
So, in your case, just fire up tcpdump and see what it dumps when you start your program. A useful call to tcpdump looks something like this:
tcpdump -i eth0 -n 'igmp and host 224.0.1.1'
To observe UDP traffic exchanges use
tcpdump -i eth0 -n 'udp and host 224.0.1.1 and port 50000'