-
-
Notifications
You must be signed in to change notification settings - Fork 118
/
setup
executable file
·267 lines (231 loc) · 10.8 KB
/
setup
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/bin/sh
LABNAME="l3-hyperv"
cd "$(dirname "$(readlink -f "$0")")"
. ../common/lab-setup
spawn vm HV1 networks 8,9,1,2
spawn vm VM1 network 1
spawn vm VM2 network 2
spawn vm HV2 networks 8,9,3
spawn vm VM3 network 3
spawn vm HV3 networks 8,9,4
spawn vm VM4 network 4
spawn vm internet networks 8,9
spawn vm RR1 network 8
spawn vm RR2 network 9
run
case $uts in
HV*)
# Create VRF
ip link add public type vrf table 90
ip link add private type vrf table 20
ip link set up dev public
ip link set up dev private
# We add some VLAN
ip link add name eth0.private link eth0 type vlan id 20
ip link add name eth1.private link eth1 type vlan id 20
ip link add name eth0.public link eth0 type vlan id 90
ip link add name eth1.public link eth1 type vlan id 90
ip link set master private dev eth0.private
ip link set master private dev eth1.private
ip link set master public dev eth0.public
ip link set master public dev eth1.public
ip link set up dev eth0.private
ip link set up dev eth1.private
ip link set up dev eth0.public
ip link set up dev eth1.public
vmifaces=""
for iface in eth2 eth3 eth4 eth5; do
[ -d /sys/class/net/$iface ] || continue
vmifaces="$vmifaces $iface"
ip link set master public dev $iface
ip link set up dev $iface
done
# Fake router IP for VM
ip addr add 203.0.113.254/32 dev public
for vmiface in $vmifaces; do
ip addr add 203.0.113.254/32 dev $vmiface
# For IPv6, this is not needed, but in case someone wants to
# configure IPv6 manually, we provide a fixed router address.
ip -6 addr add 2001:db8:cb00:7100::fe/128 dev $vmiface
done
# IP used for ECMP routing
ip addr add 198.51.100.10${uts#HV}/25 dev eth0.public
ip addr add 198.51.100.20${uts#HV}/25 dev eth1.public
ip addr add 172.22.15.10${uts#HV}/25 dev eth0.private
ip addr add 172.22.15.20${uts#HV}/25 dev eth1.private
ip -6 addr add 2001:db8:c633:6400::${uts#HV}/120 dev eth0.public
ip -6 addr add 2001:db8:c633:6401::${uts#HV}/120 dev eth1.public
# Own IP for private purpose (not really used)
ip addr add 172.22.2.${uts#HV}/32 dev dummy0
ip route add 172.22.2.${uts#HV}/32 dev dummy0 table 20
# Some firewall rules as a second level of defense. We could
# go stateless if we needed to. Another line of defense would
# be to use containers to get distinct domain of
# routing. However, it would mean for the orchestrator to also
# be able to work with containers.
cat <<EOF'' > /tmp/tools/ip46tables
#!/bin/sh
iptables "$@" && ip6tables "$@"
EOF
chmod +x /tmp/tools/ip46tables
# Safety net: enforce routing rules
for vmiface in $vmifaces; do
for iface in eth0.public eth1.public; do
ip46tables -A FORWARD -i $vmiface -o $iface -j ACCEPT
ip46tables -A FORWARD -i $iface -o $vmiface -j ACCEPT
ip46tables -A FORWARD -i $iface -o eth0.public -j ACCEPT
ip46tables -A FORWARD -i $iface -o eth1.public -j ACCEPT
done
for iface in $vmifaces; do
ip46tables -A FORWARD -i $vmiface -o $iface -j ACCEPT
done
done
ip46tables -A FORWARD -m limit --limit 5/s --limit-burst 5 \
-j LOG --log-prefix "NF: routing evasion: " --log-level warning
ip46tables -A FORWARD -j DROP
# RP filtering. We use Netfilter for that (3.3+).
ip46tables -t raw -N RPFILTER
ip46tables -t raw -A RPFILTER -m rpfilter -j RETURN
iptables -t raw -A RPFILTER -d 255.255.255.255 -p udp --sport bootpc --dport bootps -j RETURN
ip6tables -t raw -A RPFILTER -m rpfilter --accept-local -m addrtype --dst-type MULTICAST -j DROP
ip46tables -t raw -A RPFILTER -m limit --limit 5/s --limit-burst 5 \
-j LOG --log-prefix "NF: rpfilter: " --log-level warning
ip46tables -t raw -A RPFILTER -j DROP
for vmiface in $vmifaces; do
ip46tables -t raw -A PREROUTING -i $vmiface -j RPFILTER
done
# VM could access BGP/BFD. There is TTL security, but better safe than sorry.
ip46tables -N BGP-BFD
ip46tables -A INPUT -p tcp --dport bgp -j BGP-BFD
ip46tables -A INPUT -p tcp --dport 3784 -j BGP-BFD
ip46tables -A INPUT -p tcp --dport 4784 -j BGP-BFD
iptables -A BGP-BFD -s 198.51.100.0/24 -m ttl --ttl-eq 255 -j ACCEPT
iptables -A BGP-BFD -s 172.22.15.0/24 -m ttl --ttl-eq 255 -j ACCEPT
ip6tables -A BGP-BFD -s 2001:db8:c633:6400::/63 -m hl --hl-eq 255 -j ACCEPT
ip46tables -A BGP-BFD -m limit --limit 5/s --limit-burst 5 \
-j LOG --log-prefix "NF: BGP/BFD: " --log-level warning
ip46tables -A BGP-BFD -j DROP
# Don't accept redirects and don't generate them (we don't
# control how much time it takes for them to expire). As a
# router, we should not accept redirects, but better safe than
# sorry.
# accept_redirects is "AND" when forwarding is enabled
sysctl -qw net.ipv4.conf.all.accept_redirects=0
sysctl -qw net.ipv6.conf.all.accept_redirects=0
# send_redirects is "OR"
sysctl -qw net.ipv4.conf.all.send_redirects=0
sysctl -qw net.ipv4.conf.default.send_redirects=0
sysctl -qw net.ipv4.conf.eth0/public.send_redirects=0
sysctl -qw net.ipv4.conf.eth1/public.send_redirects=0
for vmiface in $vmifaces; do
sysctl -qw net.ipv4.conf.$vmiface.send_redirects=0
# Unfortunately, not possible to disable that for IPv6.
ip6tables -A OUTPUT -o $vmiface -p ipv6-icmp --icmpv6-type redirect -j DROP
done
# We do ARP proxying
sysctl -qw net.ipv4.conf.eth0/public.proxy_arp=1
sysctl -qw net.ipv4.conf.eth1/public.proxy_arp=1
for vmiface in $vmifaces; do
sysctl -qw net.ipv4.conf.$vmiface.proxy_arp=1
sysctl -qw net.ipv4.neigh.$vmiface.proxy_delay=0
done
# For IPv6, we use ndppd. Being stateless, it's safe
# enough. It may answer requests we don't have routes for, but
# that's not our problem.
# Use a public routing table and a private one
ip rule add iif public lookup 90 priority 22
ip rule add iif public unreachable priority 23
ip rule add iif private lookup 20 priority 26
ip rule add iif private unreachable priority 27
# For local lookups
ip rule add iif lo lookup main priority 51
ip rule add iif lo lookup 20 priority 52
ip rule add iif lo lookup 90 priority 53 # Last: has a default
ip rule add unreachable priority 100
# For IPv6, we don't have private stuff. So, simpler
# rules. Also, route lookup is a bit different in IPv6. Routes
# to next-hop need to be looked up as well.
ip -6 rule add lookup main priority 51
ip -6 rule add lookup 90 priority 53 # Last: has a default
ip -6 rule add unreachable priority 100
# Add routes to VM. Of course, it should be done by some kind
# of automatic registration process.
case ${uts#HV} in
1)
ip route add 203.0.113.1/32 dev eth2 table 90
ip route add 203.0.113.2/32 dev eth3 table 90
ip -6 route add 2001:db8:cb00:7100:5254:33ff:fe00:5/128 dev eth2 table 90
ip -6 route add 2001:db8:cb00:7100:5254:33ff:fe00:6/128 dev eth3 table 90
;;
2)
ip route add 203.0.113.3/32 dev eth2 table 90
ip -6 route add 2001:db8:cb00:7100:5254:33ff:fe00:a/128 dev eth2 table 90
;;
3)
ip route add 203.0.113.4/32 dev eth2 table 90
ip -6 route add 2001:db8:cb00:7100:5254:33ff:fe00:e/128 dev eth2 table 90
;;
esac
# We are a router
sysctl -qw net.ipv4.ip_forward=1
sysctl -qw net.ipv6.conf.all.forwarding=1
service bird
for vmiface in $vmifaces; do
sed s/IFACE/$vmiface/ ndppd.HV.conf >> /tmp/ndppd.conf
sed s/IFACE/$vmiface/ radvd.HV.conf >> /tmp/radvd.conf
done
service radvd ../../tmp/radvd.conf
service ndppd ../../tmp/ndppd.conf
service dnsmasq \
--no-ping \
--no-resolv \
--port 0 \
--dhcp-authoritative \
--dhcp-range=tag:known,203.0.113.0,static,255.255.255.0,infinite \
--dhcp-host=50:54:33:00:00:05,203.0.113.1,VM1 \
--dhcp-host=50:54:33:00:00:06,203.0.113.2,VM2 \
--dhcp-host=50:54:33:00:00:0a,203.0.113.3,VM3 \
--dhcp-host=50:54:33:00:00:0e,203.0.113.4,VM4 \
--dhcp-option=option:router,203.0.113.254
;;
RR*)
ip link add name eth0.public link eth0 type vlan id 90
ip link add name eth0.private link eth0 type vlan id 20
ip link set up dev eth0.public
ip link set up dev eth0.private
ip addr add 198.51.100.${uts#RR}26/25 dev eth0.public
ip addr add 172.22.15.${uts#RR}26/25 dev eth0.private
ip -6 addr add 2001:db8:c633:640$((${uts#RR} - 1))::26/120 dev eth0.public
service bird
;;
VM*)
# Classic DHCP request for IPv4
[ ! -d /etc/dhcp ] || mount -n -t tmpfs tmpfs /etc/dhcp -o rw
service dhclient -v -4 -1 eth0 -lf /tmp/dhcp.leases -cf /dev/null
# For IPv6, they will get RA
;;
internet)
ip link add name eth0.public link eth0 type vlan id 90
ip link add name eth1.public link eth1 type vlan id 90
ip link set up dev eth0.public
ip link set up dev eth1.public
# For ECMP routing
ip addr add 198.51.100.1/25 dev eth0.public
ip addr add 198.51.100.254/25 dev eth1.public
ip -6 addr add 2001:db8:c633:6400::ff/120 dev eth0.public
ip -6 addr add 2001:db8:c633:6401::ff/120 dev eth1.public
# Routing
ip rule add iif lo lookup main priority 51
ip rule add iif lo lookup 90 priority 53 # Last: has a default
ip -6 rule add lookup main priority 51
ip -6 rule add lookup 90 priority 53 # Last: has a default
# We are a router
sysctl -qw net.ipv4.ip_forward=1
sysctl -qw net.ipv6.conf.all.forwarding=1
service bird
# "Internet"
ip addr add 8.8.8.8/32 dev dummy0
ip -6 addr add 2001:4860:4860::8888/128 dev dummy0
;;
esac
service nginx