forked from dv336699/csf-post-docker
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdocker.sh
134 lines (104 loc) · 5.2 KB
/
docker.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/bin/sh
export PATH="$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
chain_exists() {
[ $# -lt 1 -o $# -gt 2 ] && {
echo "Usage: chain_exists <chain_name> [table]" >&2
return 1
}
local chain_name="$1" ; shift
[ $# -eq 1 ] && local table="--table $1"
iptables $table -n --list "$chain_name" >/dev/null 2>&1
}
add_to_forward() {
local docker_int=$1
if [ `iptables -nvL FORWARD | grep ${docker_int} | wc -l` -eq 0 ]; then
iptables -A FORWARD -o ${docker_int} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -o ${docker_int} -j DOCKER
iptables -A FORWARD -i ${docker_int} ! -o ${docker_int} -j ACCEPT
iptables -A FORWARD -i ${docker_int} -o ${docker_int} -j ACCEPT
fi
}
add_to_nat() {
local docker_int=$1
local subnet=$2
iptables -t nat -A POSTROUTING -s ${subnet} ! -o ${docker_int} -j MASQUERADE
iptables -t nat -A DOCKER -i ${docker_int} -j RETURN
}
add_to_docker_isolation() {
local docker_int=$1
iptables -A DOCKER-ISOLATION-STAGE-1 -i ${docker_int} ! -o ${docker_int} -j DOCKER-ISOLATION-STAGE-2
iptables -A DOCKER-ISOLATION-STAGE-2 -o ${docker_int} -j DROP
}
DOCKER_INT="docker0"
DOCKER_NETWORK="172.17.0.0/16"
iptables-save | grep -v -- '-j DOCKER' | iptables-restore
chain_exists DOCKER && iptables -X DOCKER
chain_exists DOCKER nat && iptables -t nat -X DOCKER
iptables -N DOCKER
iptables -N DOCKER-ISOLATION-STAGE-1
iptables -N DOCKER-ISOLATION-STAGE-2
iptables -N DOCKER-USER
iptables -t nat -N DOCKER
iptables -A FORWARD -j DOCKER-USER
iptables -A FORWARD -j DOCKER-ISOLATION-STAGE-1
add_to_forward ${DOCKER_INT}
iptables -t nat -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
iptables -t nat -A POSTROUTING -s ${DOCKER_NETWORK} ! -o ${DOCKER_INT} -j MASQUERADE
bridges=`docker network ls -q --filter='Driver=bridge'`
for bridge in $bridges; do
DOCKER_NET_INT=`docker network inspect -f '{{"'br-$bridge'" | or (index .Options "com.docker.network.bridge.name")}}' $bridge`
subnet=`docker network inspect -f '{{(index .IPAM.Config 0).Subnet}}' $bridge`
add_to_nat ${DOCKER_NET_INT} ${subnet}
add_to_forward ${DOCKER_NET_INT}
add_to_docker_isolation ${DOCKER_NET_INT}
# Allow Host machine to access to container ports
iptables -I INPUT -i ${DOCKER_NET_INT} -j ACCEPT
done
containers=`docker ps -q`
if [ `echo ${containers} | wc -c` -gt "1" ]; then
for container in ${containers}; do
netmode=`docker inspect -f "{{.HostConfig.NetworkMode}}" ${container}`
if [ "$netmode" = "default" ]; then
DOCKER_NET_INT=${DOCKER_INT}
ipaddr=`docker inspect -f "{{.NetworkSettings.IPAddress}}" ${container}`
else
netmode_search=`docker network ls --filter name=${netmode} --format {{.Name}}`
if [ "$netmode_search" = "" ]; then
netmode_search=`docker network ls --filter id=${netmode} --format {{.Name}}`
fi
if [ "$netmode_search" != "" ]; then
netmode=$netmode_search
fi
bridge=$(docker inspect -f "{{.NetworkSettings.Networks.${netmode}.NetworkID}}" ${container} | cut -c -12)
DOCKER_NET_INT=`docker network inspect -f '{{"'br-$bridge'" | or (index .Options "com.docker.network.bridge.name")}}' $bridge`
ipaddr=`docker inspect -f "{{.NetworkSettings.Networks.${netmode}.IPAddress}}" ${container}`
fi
rules=`docker port ${container} | sed 's/ //g'`
if [ `echo ${rules} | wc -c` -gt "1" ]; then
for rule in ${rules}; do
src=`echo ${rule} | awk -F'->' '{ print $2 }'`
dst=`echo ${rule} | awk -F'->' '{ print $1 }'`
src_ip=`echo ${src} | awk -F':' '{ print $1 }'`
src_port=`echo ${src} | awk -F':' '{ print $2 }'`
dst_port=`echo ${dst} | awk -F'/' '{ print $1 }'`
dst_proto=`echo ${dst} | awk -F'/' '{ print $2 }'`
iptables -A DOCKER -d ${ipaddr}/32 ! -i ${DOCKER_NET_INT} -o ${DOCKER_NET_INT} -p ${dst_proto} -m ${dst_proto} --dport ${dst_port} -j ACCEPT
iptables -t nat -A POSTROUTING -s ${ipaddr}/32 -d ${ipaddr}/32 -p ${dst_proto} -m ${dst_proto} --dport ${dst_port} -j MASQUERADE
iptables_opt_src=""
if [ ${src_ip} != "0.0.0.0" ]; then
iptables_opt_src="-d ${src_ip}/32 "
fi
iptables -t nat -A DOCKER ${iptables_opt_src}! -i ${DOCKER_NET_INT} -p ${dst_proto} -m ${dst_proto} --dport ${src_port} -j DNAT --to-destination ${ipaddr}:${dst_port}
# Allow access from localhost inside container, eg: "curl -v localhost" or via SSH tunnel.
iptables -I OUTPUT -o ${DOCKER_NET_INT} -d ${ipaddr}/32 -p ${dst_proto} -m ${dst_proto} --dport ${dst_port} -j ACCEPT
done
fi
done
fi
iptables -A DOCKER-ISOLATION-STAGE-1 -j RETURN
iptables -A DOCKER-ISOLATION-STAGE-2 -j RETURN
iptables -A DOCKER-USER -j RETURN
if [ `iptables -t nat -nvL DOCKER | grep ${DOCKER_INT} | wc -l` -eq 0 ]; then
iptables -t nat -I DOCKER -i ${DOCKER_INT} -j RETURN
fi