This repository has been archived by the owner on Sep 23, 2020. It is now read-only.
/
kvm-ebtables-config.sh
executable file
·217 lines (174 loc) · 5.19 KB
/
kvm-ebtables-config.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
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
#!/bin/bash
# Copyright 1999-2010 University of Chicago
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy
# of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
# For more information see: http://www.nimbusproject.org
#########
# ABOUT #
#########
# This script adjusts ebtables rules to prevent MAC and IP spoofing.
# Unlike the 'main' ebtables-config script used with Xen, this will NOT allow
# you to stop DHCP packets from workspaces escaping to the site network.
# 1. Is the packet coming from a workspace virtual interface?
# 2. If not, proceed without further processing.
# 3. If so, is the MAC address incorrect? Drop the packet.
# 4. Is this is a DHCP packet?
# 5. If so, allow it to be bridged.
# 6. If not a DHCP packet, it must have the correct source IP address,
# otherwise the packet is dropped.
#######################
# ADJUST AS NECESSARY #
#######################
# NOTE: The ebtables path is configured here in order to make sure that if
# someone compromises the privileged account, it cannot use the sudo
# privilige of running this program to do more than desired.
PATH=/bin:/usr/bin:/sbin
export PATH
EBTABLES=ebtables
#EBTABLES=/sbin/ebtables
#EBTABLES=/usr/sbin/ebtables
FLOCKFILE=/var/lock/ebtables.config.lock
FLOCK=/usr/bin/flock
if [ ! -f $FLOCK ]; then
echo "*** can not find flock program, disabling"
echo "*** disabling flock might result in a error like \"kernel doesn't support a certain ebtables extension\""
FLOCK=/bin/true
fi
#############
# ARGUMENTS #
#############
if [ $# -lt 2 ]; then
echo "ERROR: requires at least 2 arguments, syntax: add|rem <vifname> [<dhcpif> <macaddr> <ipaddr>]"
exit 1
fi
ADDREM=$1
echo " subcommand: $ADDREM"
VIFNAME=$2
echo " vifname: $VIFNAME"
if [ "$ADDREM" != "add" ] && [ "$ADDREM" != "rem" ]; then
echo "ERROR: subcommand must be 'add' or 'rem'"
exit 1
fi
if [ "$ADDREM" = "add" ]; then
if [ $# -ne 5 ]; then
echo "ERROR: add requires 5 arguments: add <vifname> <dhcpif> <macaddr> <ipaddr>"
exit 1
else
DHCPIF=$3
echo " dhcpif (ignored): $DHCPIF"
MACADDR=$4
echo " macaddr: $MACADDR"
IPADDR=$5
echo " ipaddr: $IPADDR"
fi
fi
if [ "$ADDREM" = "rem" ] && [ $# -ne 2 ]; then
echo "ERROR: rem requires just 2 arguments: rem <vifname>"
exit 1
fi
###################################
#### EBTABLES CHAINS AND RULES ####
###################################
# function init_vifname_chain
#
# This chain is the target that all packets from a workspace NIC are
# sent. All packets must have the correct source MAC address. Any
# DHCP request must be sent to the appropriate dhcpif chain. If it
# is not a DHCP request, it must have the correct source IP address.
function init_vifname_chain() {
$EBTABLES -N $VIFNAME
if [ $? -ne 0 ]; then
echo "ERROR: could not create $VIFNAME chain"
return 1
fi
$EBTABLES -P $VIFNAME ACCEPT
if [ $? -ne 0 ]; then
echo "ERROR: could not set default policy for $VIFNAME chain"
return 1
fi
# First make sure it is using the right MAC address
$EBTABLES -A $VIFNAME -s ! $MACADDR -j DROP
if [ $? -ne 0 ]; then
echo "ERROR: could not set MAC address policy for $VIFNAME chain"
return 1
fi
# If this is a DHCP request, accept it
$EBTABLES -A $VIFNAME -p IPv4 --ip-proto 17 --ip-dport 67 -j ACCEPT
if [ $? -ne 0 ]; then
echo "ERROR: could not set DHCP policy for $VIFNAME chain"
return 1
fi
# Make sure it using the right IP address (this needs to be after the
# DHCP handler branch since those packets do not have IPs yet).
$EBTABLES -A $VIFNAME -p IPv4 --ip-src ! $IPADDR -j DROP
if [ $? -ne 0 ]; then
echo "ERROR: could not set IP policy for $VIFNAME chain"
return 1
fi
return 0
}
function delete_vifname_chain() {
$EBTABLES -X $VIFNAME
return $?
}
function add_input_rule() {
$EBTABLES -A INPUT -i $VIFNAME -j $VIFNAME
return $?
}
function rem_input_rule() {
$EBTABLES -D INPUT -i $VIFNAME -j $VIFNAME
return $?
}
##########################
#### SUBCOMMAND IMPLS ####
##########################
(
$FLOCK -x 200
if [ "$ADDREM" = "rem" ]; then
SUCCESS="y"
rem_input_rule
if [ $? -ne 0 ]; then
echo "ERROR: Failed to remove $VIFNAME INPUT rule"
SUCCESS="n"
else
echo "Removed $VIFNAME INPUT rule"
fi
delete_vifname_chain
if [ $? -ne 0 ]; then
echo "ERROR: Failed to delete $VIFNAME chain"
SUCCESS="n"
else
echo "Deleted $VIFNAME chain"
fi
if [ "$SUCCESS" = "n" ]; then
exit 1
fi
exit 0
fi
if [ "$ADDREM" = "add" ]; then
init_vifname_chain
if [ $? -ne 0 ]; then
exit 1
else
echo "Created $VIFNAME chain"
fi
add_input_rule
if [ $? -ne 0 ]; then
echo "ERROR: Failed to add $VIFNAME INPUT rule"
exit 1
else
echo "Added $VIFNAME INPUT rule"
exit 0
fi
fi
) 200>$FLOCKFILE