Fixed up IPtables rules to be more strict

This commit is contained in:
Daniel P. Berrange 2007-04-10 23:17:46 +00:00
parent 7fd0878c40
commit 19c6ddcce5
6 changed files with 343 additions and 187 deletions

View File

@ -1,3 +1,10 @@
Tue Apr 10 19:17:29 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* qemud/conf.c, qemu/internal.h, qemud/iptables.c, qemud/iptables.h,
qemud/qemud.c: Some adjustment to IPTables rules to tighten up traffic
flow to/from virtual networks & avoid accidentally NAT'ing wrong packets.
Fixed XML dump when using auto-generated bridge device name.
Tue Apr 10 19:15:29 EST 2007 Daniel P. Berrange <berrange@redhat.com> Tue Apr 10 19:15:29 EST 2007 Daniel P. Berrange <berrange@redhat.com>
* python/libvir.c, python/libvirt-python-api.xml: Added manual * python/libvir.c, python/libvirt-python-api.xml: Added manual

View File

@ -32,6 +32,8 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <arpa/inet.h>
#include <libxml/parser.h> #include <libxml/parser.h>
#include <libxml/tree.h> #include <libxml/tree.h>
@ -44,7 +46,6 @@
#include "internal.h" #include "internal.h"
#include "conf.h" #include "conf.h"
#include "driver.h" #include "driver.h"
#include "iptables.h"
#include "uuid.h" #include "uuid.h"
#include "buf.h" #include "buf.h"
@ -1127,15 +1128,6 @@ qemudNetworkIfaceConnect(struct qemud_server *server,
goto error; goto error;
} }
if (net->type == QEMUD_NET_NETWORK && network->def->forward) {
if ((err = iptablesAddPhysdevForward(server->iptables, ifname))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"Failed to add iptables rule to allow bridging from '%s' :%s",
ifname, strerror(err));
goto error;
}
}
snprintf(tapfdstr, sizeof(tapfdstr), "tap,fd=%d,script=,vlan=%d", tapfd, vlan); snprintf(tapfdstr, sizeof(tapfdstr), "tap,fd=%d,script=,vlan=%d", tapfd, vlan);
if (!(retval = strdup(tapfdstr))) if (!(retval = strdup(tapfdstr)))
@ -1151,8 +1143,6 @@ qemudNetworkIfaceConnect(struct qemud_server *server,
return retval; return retval;
no_memory: no_memory:
if (net->type == QEMUD_NET_NETWORK && network->def->forward)
iptablesRemovePhysdevForward(server->iptables, ifname);
qemudReportError(server, VIR_ERR_NO_MEMORY, "tapfds"); qemudReportError(server, VIR_ERR_NO_MEMORY, "tapfds");
error: error:
if (retval) if (retval)
@ -1765,6 +1755,21 @@ static int qemudParseInetXML(struct qemud_server *server ATTRIBUTE_UNUSED,
netmask = NULL; netmask = NULL;
} }
if (def->ipAddress[0] && def->netmask[0]) {
struct in_addr inaddress, innetmask;
char *netaddr;
inet_aton((const char*)def->ipAddress, &inaddress);
inet_aton((const char*)def->netmask, &innetmask);
inaddress.s_addr &= innetmask.s_addr;
netaddr = inet_ntoa(inaddress);
snprintf(def->network,sizeof(def->network)-1,
"%s/%s", netaddr, (const char *)def->netmask);
}
cur = node->children; cur = node->children;
while (cur != NULL) { while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE && if (cur->type == XML_ELEMENT_NODE &&
@ -1835,9 +1840,37 @@ static struct qemud_network_def *qemudParseNetworkXML(struct qemud_server *serve
} }
xmlXPathFreeObject(obj); xmlXPathFreeObject(obj);
/* Parse bridge information */
obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseBridgeXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error;
}
}
xmlXPathFreeObject(obj);
/* Parse IP information */
obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseInetXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error;
}
}
xmlXPathFreeObject(obj);
/* IPv4 forwarding setup */
obj = xmlXPathEval(BAD_CAST "count(/network/forward) > 0", ctxt); obj = xmlXPathEval(BAD_CAST "count(/network/forward) > 0", ctxt);
if ((obj != NULL) && (obj->type == XPATH_BOOLEAN) && if ((obj != NULL) && (obj->type == XPATH_BOOLEAN) &&
obj->boolval) { obj->boolval) {
if (!def->ipAddress[0] ||
!def->netmask[0]) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"Forwarding requested, but no IPv4 address/netmask provided");
goto error;
}
def->forward = 1; def->forward = 1;
tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@dev)", ctxt); tmp = xmlXPathEval(BAD_CAST "string(/network/forward[1]/@dev)", ctxt);
if ((tmp != NULL) && (tmp->type == XPATH_STRING) && if ((tmp != NULL) && (tmp->type == XPATH_STRING) &&
@ -1860,26 +1893,6 @@ static struct qemud_network_def *qemudParseNetworkXML(struct qemud_server *serve
} }
xmlXPathFreeObject(obj); xmlXPathFreeObject(obj);
/* Parse bridge information */
obj = xmlXPathEval(BAD_CAST "/network/bridge[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseBridgeXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error;
}
}
xmlXPathFreeObject(obj);
/* Parse IP information */
obj = xmlXPathEval(BAD_CAST "/network/ip[1]", ctxt);
if ((obj != NULL) && (obj->type == XPATH_NODESET) &&
(obj->nodesetval != NULL) && (obj->nodesetval->nodeNr > 0)) {
if (!qemudParseInetXML(server, def, obj->nodesetval->nodeTab[0])) {
goto error;
}
}
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctxt); xmlXPathFreeContext(ctxt);
return def; return def;
@ -2622,7 +2635,7 @@ char *qemudGenerateXML(struct qemud_server *server,
char *qemudGenerateNetworkXML(struct qemud_server *server, char *qemudGenerateNetworkXML(struct qemud_server *server,
struct qemud_network *network ATTRIBUTE_UNUSED, struct qemud_network *network,
struct qemud_network_def *def) { struct qemud_network_def *def) {
bufferPtr buf = 0; bufferPtr buf = 0;
unsigned char *uuid; unsigned char *uuid;
@ -2654,9 +2667,15 @@ char *qemudGenerateNetworkXML(struct qemud_server *server,
} }
} }
if ((def->bridge != '\0' || def->disableSTP || def->forwardDelay) && bufferAdd(buf, " <bridge", -1);
bufferVSprintf(buf, " <bridge name='%s' stp='%s' delay='%d' />\n", if (qemudIsActiveNetwork(network)) {
def->bridge, if (bufferVSprintf(buf, " name='%s'", network->bridge) < 0)
goto no_memory;
} else if (def->bridge[0]) {
if (bufferVSprintf(buf, " name='%s'", def->bridge) < 0)
goto no_memory;
}
if (bufferVSprintf(buf, " stp='%s' forwardDelay='%d' />\n",
def->disableSTP ? "off" : "on", def->disableSTP ? "off" : "on",
def->forwardDelay) < 0) def->forwardDelay) < 0)
goto no_memory; goto no_memory;

View File

@ -250,6 +250,7 @@ struct qemud_network_def {
char ipAddress[BR_INET_ADDR_MAXLEN]; char ipAddress[BR_INET_ADDR_MAXLEN];
char netmask[BR_INET_ADDR_MAXLEN]; char netmask[BR_INET_ADDR_MAXLEN];
char network[BR_INET_ADDR_MAXLEN+BR_INET_ADDR_MAXLEN+1];
int nranges; int nranges;
struct qemud_dhcp_range_def *ranges; struct qemud_dhcp_range_def *ranges;

View File

@ -656,49 +656,29 @@ iptablesRemoveUdpInput(iptablesContext *ctx,
return iptablesInput(ctx, iface, port, REMOVE, 0); return iptablesInput(ctx, iface, port, REMOVE, 0);
} }
/* Allow all traffic coming from the bridge, with a valid network address
* to proceed to WAN
*/
static int static int
iptablesPhysdevForward(iptablesContext *ctx, iptablesForwardAllowOut(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *physdev,
int action) int action)
{ {
if (physdev && physdev[0]) {
return iptablesAddRemoveRule(ctx->forward_filter, return iptablesAddRemoveRule(ctx->forward_filter,
action, action,
"--match", "physdev", "--source", network,
"--physdev-in", iface,
"--jump", "ACCEPT",
NULL);
}
int
iptablesAddPhysdevForward(iptablesContext *ctx,
const char *iface)
{
return iptablesPhysdevForward(ctx, iface, ADD);
}
int
iptablesRemovePhysdevForward(iptablesContext *ctx,
const char *iface)
{
return iptablesPhysdevForward(ctx, iface, REMOVE);
}
static int
iptablesInterfaceForward(iptablesContext *ctx,
const char *iface,
const char *target,
int action)
{
if (target && target[0]) {
return iptablesAddRemoveRule(ctx->forward_filter,
action,
"--in-interface", iface, "--in-interface", iface,
"--out-interface", target, "--out-interface", physdev,
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
} else { } else {
return iptablesAddRemoveRule(ctx->forward_filter, return iptablesAddRemoveRule(ctx->forward_filter,
action, action,
"--source", network,
"--in-interface", iface, "--in-interface", iface,
"--jump", "ACCEPT", "--jump", "ACCEPT",
NULL); NULL);
@ -706,31 +686,39 @@ iptablesInterfaceForward(iptablesContext *ctx,
} }
int int
iptablesAddInterfaceForward(iptablesContext *ctx, iptablesAddForwardAllowOut(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *target) const char *physdev)
{ {
return iptablesInterfaceForward(ctx, iface, target, ADD); return iptablesForwardAllowOut(ctx, network, iface, physdev, ADD);
} }
int int
iptablesRemoveInterfaceForward(iptablesContext *ctx, iptablesRemoveForwardAllowOut(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *target) const char *physdev)
{ {
return iptablesInterfaceForward(ctx, iface, target, REMOVE); return iptablesForwardAllowOut(ctx, network, iface, physdev, REMOVE);
} }
/* Allow all traffic destined to the bridge, with a valid network address
* and associated with an existing connection
*/
static int static int
iptablesStateForward(iptablesContext *ctx, iptablesForwardAllowIn(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *target, const char *physdev,
int action) int action)
{ {
if (target && target[0]) { if (physdev && physdev[0]) {
return iptablesAddRemoveRule(ctx->forward_filter, return iptablesAddRemoveRule(ctx->forward_filter,
action, action,
"--in-interface", target, "--destination", network,
"--in-interface", physdev,
"--out-interface", iface, "--out-interface", iface,
"--match", "state", "--match", "state",
"--state", "ESTABLISHED,RELATED", "--state", "ESTABLISHED,RELATED",
@ -739,6 +727,7 @@ iptablesStateForward(iptablesContext *ctx,
} else { } else {
return iptablesAddRemoveRule(ctx->forward_filter, return iptablesAddRemoveRule(ctx->forward_filter,
action, action,
"--destination", network,
"--out-interface", iface, "--out-interface", iface,
"--match", "state", "--match", "state",
"--state", "ESTABLISHED,RELATED", "--state", "ESTABLISHED,RELATED",
@ -748,56 +737,154 @@ iptablesStateForward(iptablesContext *ctx,
} }
int int
iptablesAddStateForward(iptablesContext *ctx, iptablesAddForwardAllowIn(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *target) const char *physdev)
{ {
return iptablesStateForward(ctx, iface, target, ADD); return iptablesForwardAllowIn(ctx, network, iface, physdev, ADD);
} }
int int
iptablesRemoveStateForward(iptablesContext *ctx, iptablesRemoveForwardAllowIn(iptablesContext *ctx,
const char *network,
const char *iface, const char *iface,
const char *target) const char *physdev)
{ {
return iptablesStateForward(ctx, iface, target, REMOVE); return iptablesForwardAllowIn(ctx, network, iface, physdev, REMOVE);
} }
/* Allow all traffic between guests on the same bridge,
* with a valid network address
*/
static int static int
iptablesNonBridgedMasq(iptablesContext *ctx, iptablesForwardAllowCross(iptablesContext *ctx,
const char *target, const char *iface,
int action) int action)
{ {
if (target && target[0]) { return iptablesAddRemoveRule(ctx->forward_filter,
action,
"--in-interface", iface,
"--out-interface", iface,
"--jump", "ACCEPT",
NULL);
}
int
iptablesAddForwardAllowCross(iptablesContext *ctx,
const char *iface) {
return iptablesForwardAllowCross(ctx, iface, ADD);
}
int
iptablesRemoveForwardAllowCross(iptablesContext *ctx,
const char *iface) {
return iptablesForwardAllowCross(ctx, iface, REMOVE);
}
/* Drop all traffic trying to forward from the bridge.
* ie the bridge is the in interface
*/
static int
iptablesForwardRejectOut(iptablesContext *ctx,
const char *iface,
int action)
{
return iptablesAddRemoveRule(ctx->forward_filter,
action,
"--in-interface", iface,
"--jump", "REJECT",
NULL);
}
int
iptablesAddForwardRejectOut(iptablesContext *ctx,
const char *iface)
{
return iptablesForwardRejectOut(ctx, iface, ADD);
}
int
iptablesRemoveForwardRejectOut(iptablesContext *ctx,
const char *iface)
{
return iptablesForwardRejectOut(ctx, iface, REMOVE);
}
/* Drop all traffic trying to forward to the bridge.
* ie the bridge is the out interface
*/
static int
iptablesForwardRejectIn(iptablesContext *ctx,
const char *iface,
int action)
{
return iptablesAddRemoveRule(ctx->forward_filter,
action,
"--out-interface", iface,
"--jump", "REJECT",
NULL);
}
int
iptablesAddForwardRejectIn(iptablesContext *ctx,
const char *iface)
{
return iptablesForwardRejectIn(ctx, iface, ADD);
}
int
iptablesRemoveForwardRejectIn(iptablesContext *ctx,
const char *iface)
{
return iptablesForwardRejectIn(ctx, iface, REMOVE);
}
/* Masquerade all traffic coming from the network associated
* with the bridge
*/
static int
iptablesForwardMasquerade(iptablesContext *ctx,
const char *network,
const char *physdev,
int action)
{
if (physdev && physdev[0]) {
return iptablesAddRemoveRule(ctx->nat_postrouting, return iptablesAddRemoveRule(ctx->nat_postrouting,
action, action,
"--out-interface", target, "--source", network,
"--match", "physdev", "--out-interface", physdev,
"!", "--physdev-is-bridged",
"--jump", "MASQUERADE", "--jump", "MASQUERADE",
NULL); NULL);
} else { } else {
return iptablesAddRemoveRule(ctx->nat_postrouting, return iptablesAddRemoveRule(ctx->nat_postrouting,
action, action,
"--match", "physdev", "--source", network,
"!", "--physdev-is-bridged",
"--jump", "MASQUERADE", "--jump", "MASQUERADE",
NULL); NULL);
} }
} }
int int
iptablesAddNonBridgedMasq(iptablesContext *ctx, iptablesAddForwardMasquerade(iptablesContext *ctx,
const char *target) const char *network,
const char *physdev)
{ {
return iptablesNonBridgedMasq(ctx, target, ADD); return iptablesForwardMasquerade(ctx, network, physdev, ADD);
} }
int int
iptablesRemoveNonBridgedMasq(iptablesContext *ctx, iptablesRemoveForwardMasquerade(iptablesContext *ctx,
const char *target) const char *network,
const char *physdev)
{ {
return iptablesNonBridgedMasq(ctx, target, REMOVE); return iptablesForwardMasquerade(ctx, network, physdev, REMOVE);
} }
/* /*

View File

@ -43,29 +43,45 @@ int iptablesRemoveUdpInput (iptablesContext *ctx,
const char *iface, const char *iface,
int port); int port);
int iptablesAddPhysdevForward (iptablesContext *ctx, int iptablesAddForwardAllowOut (iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev);
int iptablesRemoveForwardAllowOut (iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev);
int iptablesAddForwardAllowIn (iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev);
int iptablesRemoveForwardAllowIn (iptablesContext *ctx,
const char *network,
const char *iface,
const char *physdev);
int iptablesAddForwardAllowCross (iptablesContext *ctx,
const char *iface); const char *iface);
int iptablesRemovePhysdevForward (iptablesContext *ctx, int iptablesRemoveForwardAllowCross (iptablesContext *ctx,
const char *iface); const char *iface);
int iptablesAddInterfaceForward (iptablesContext *ctx, int iptablesAddForwardRejectOut (iptablesContext *ctx,
const char *iface, const char *iface);
const char *target); int iptablesRemoveForwardRejectOut (iptablesContext *ctx,
int iptablesRemoveInterfaceForward (iptablesContext *ctx, const char *iface);
const char *iface,
const char *target);
int iptablesAddStateForward (iptablesContext *ctx, int iptablesAddForwardRejectIn (iptablesContext *ctx,
const char *iface, const char *iface);
const char *target); int iptablesRemoveForwardRejectIn (iptablesContext *ctx,
int iptablesRemoveStateForward (iptablesContext *ctx, const char *iface);
const char *iface,
const char *target);
int iptablesAddNonBridgedMasq (iptablesContext *ctx, int iptablesAddForwardMasquerade (iptablesContext *ctx,
const char *target); const char *network,
int iptablesRemoveNonBridgedMasq (iptablesContext *ctx, const char *physdev);
const char *target); int iptablesRemoveForwardMasquerade (iptablesContext *ctx,
const char *network,
const char *physdev);
#endif /* __QEMUD_IPTABLES_H__ */ #endif /* __QEMUD_IPTABLES_H__ */

View File

@ -45,6 +45,7 @@
#include <getopt.h> #include <getopt.h>
#include <ctype.h> #include <ctype.h>
#include <libvirt/virterror.h> #include <libvirt/virterror.h>
#include "internal.h" #include "internal.h"
@ -1041,26 +1042,8 @@ static int qemudVMData(struct qemud_server *server ATTRIBUTE_UNUSED,
} }
} }
static void
qemudNetworkIfaceDisconnect(struct qemud_server *server,
struct qemud_vm *vm ATTRIBUTE_UNUSED,
struct qemud_vm_net_def *net) {
struct qemud_network *network;
if (net->type != QEMUD_NET_NETWORK)
return;
if (!(network = qemudFindNetworkByName(server, net->dst.network.name))) {
return;
} else if (network->bridge[0] == '\0') {
return;
}
iptablesRemovePhysdevForward(server->iptables, net->dst.network.ifname);
}
int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) { int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
struct qemud_vm_net_def *net;
if (!qemudIsActiveVM(vm)) if (!qemudIsActiveVM(vm))
return 0; return 0;
@ -1079,13 +1062,6 @@ int qemudShutdownVMDaemon(struct qemud_server *server, struct qemud_vm *vm) {
vm->monitor = -1; vm->monitor = -1;
server->nvmfds -= 2; server->nvmfds -= 2;
net = vm->def->nets;
while (net) {
if (net->type == QEMUD_NET_NETWORK)
qemudNetworkIfaceDisconnect(server, vm, net);
net = net->next;
}
if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) { if (waitpid(vm->pid, NULL, WNOHANG) != vm->pid) {
kill(vm->pid, SIGKILL); kill(vm->pid, SIGKILL);
if (waitpid(vm->pid, NULL, 0) != vm->pid) { if (waitpid(vm->pid, NULL, 0) != vm->pid) {
@ -1251,27 +1227,20 @@ qemudAddIptablesRules(struct qemud_server *server,
return 1; return 1;
} }
/* allow bridging from the bridge interface itself */
if ((err = iptablesAddPhysdevForward(server->iptables, network->bridge))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow bridging from '%s' : %s\n",
network->bridge, strerror(err));
goto err1;
}
/* allow DHCP requests through to dnsmasq */ /* allow DHCP requests through to dnsmasq */
if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 67))) { if ((err = iptablesAddTcpInput(server->iptables, network->bridge, 67))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow DHCP requests from '%s' : %s\n", "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err2; goto err1;
} }
if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 67))) { if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 67))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow DHCP requests from '%s' : %s\n", "failed to add iptables rule to allow DHCP requests from '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err3; goto err2;
} }
/* allow DNS requests through to dnsmasq */ /* allow DNS requests through to dnsmasq */
@ -1279,60 +1248,107 @@ qemudAddIptablesRules(struct qemud_server *server,
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow DNS requests from '%s' : %s\n", "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err4; goto err3;
} }
if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 53))) { if ((err = iptablesAddUdpInput(server->iptables, network->bridge, 53))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow DNS requests from '%s' : %s\n", "failed to add iptables rule to allow DNS requests from '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err4;
}
/* Catch all rules to block forwarding to/from bridges */
if ((err = iptablesAddForwardRejectOut(server->iptables, network->bridge))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to block outbound traffic from '%s' : %s\n",
network->bridge, strerror(err));
goto err5; goto err5;
} }
if ((err = iptablesAddForwardRejectIn(server->iptables, network->bridge))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to block inbound traffic to '%s' : %s\n",
network->bridge, strerror(err));
goto err6;
}
/* Allow traffic between guests on the same bridge */
if ((err = iptablesAddForwardAllowCross(server->iptables, network->bridge))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow cross bridge traffic on '%s' : %s\n",
network->bridge, strerror(err));
goto err7;
}
/* The remaining rules are only needed for IP forwarding */ /* The remaining rules are only needed for IP forwarding */
if (!network->def->forward) if (!network->def->forward)
return 1; return 1;
/* allow forwarding packets from the bridge interface */ /* allow forwarding packets from the bridge interface */
if ((err = iptablesAddInterfaceForward(server->iptables, network->bridge, network->def->forwardDev))) { if ((err = iptablesAddForwardAllowOut(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow forwarding from '%s' : %s\n", "failed to add iptables rule to allow forwarding from '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err6; goto err8;
} }
/* allow forwarding packets to the bridge interface if they are part of an existing connection */ /* allow forwarding packets to the bridge interface if they are part of an existing connection */
if ((err = iptablesAddStateForward(server->iptables, network->bridge, network->def->forwardDev))) { if ((err = iptablesAddForwardAllowIn(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to allow forwarding to '%s' : %s\n", "failed to add iptables rule to allow forwarding to '%s' : %s\n",
network->bridge, strerror(err)); network->bridge, strerror(err));
goto err7; goto err9;
} }
/* enable masquerading */ /* enable masquerading */
if ((err = iptablesAddNonBridgedMasq(server->iptables, network->def->forwardDev))) { if ((err = iptablesAddForwardMasquerade(server->iptables,
network->def->network,
network->def->forwardDev))) {
qemudReportError(server, VIR_ERR_INTERNAL_ERROR, qemudReportError(server, VIR_ERR_INTERNAL_ERROR,
"failed to add iptables rule to enable masquerading : %s\n", "failed to add iptables rule to enable masquerading : %s\n",
strerror(err)); strerror(err));
goto err8; goto err10;
} }
return 1; return 1;
err10:
iptablesRemoveForwardAllowIn(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev);
err9:
iptablesRemoveForwardAllowOut(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev);
err8: err8:
iptablesRemoveStateForward(server->iptables, network->bridge, network->def->forwardDev); iptablesRemoveForwardAllowCross(server->iptables,
network->bridge);
err7: err7:
iptablesRemoveInterfaceForward(server->iptables, network->bridge, network->def->forwardDev); iptablesRemoveForwardRejectIn(server->iptables,
network->bridge);
err6: err6:
iptablesRemoveUdpInput(server->iptables, network->bridge, 53); iptablesRemoveForwardRejectOut(server->iptables,
network->bridge);
err5: err5:
iptablesRemoveTcpInput(server->iptables, network->bridge, 53); iptablesRemoveUdpInput(server->iptables, network->bridge, 53);
err4: err4:
iptablesRemoveUdpInput(server->iptables, network->bridge, 67); iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
err3: err3:
iptablesRemoveTcpInput(server->iptables, network->bridge, 67); iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
err2: err2:
iptablesRemovePhysdevForward(server->iptables, network->bridge); iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
err1: err1:
return 0; return 0;
} }
@ -1341,15 +1357,25 @@ static void
qemudRemoveIptablesRules(struct qemud_server *server, qemudRemoveIptablesRules(struct qemud_server *server,
struct qemud_network *network) { struct qemud_network *network) {
if (network->def->forward) { if (network->def->forward) {
iptablesRemoveNonBridgedMasq(server->iptables, network->def->forwardDev); iptablesRemoveForwardMasquerade(server->iptables,
iptablesRemoveStateForward(server->iptables, network->bridge, network->def->forwardDev); network->def->network,
iptablesRemoveInterfaceForward(server->iptables, network->bridge, network->def->forwardDev); network->def->forwardDev);
iptablesRemoveForwardAllowIn(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev);
iptablesRemoveForwardAllowOut(server->iptables,
network->def->network,
network->bridge,
network->def->forwardDev);
} }
iptablesRemoveForwardAllowCross(server->iptables, network->bridge);
iptablesRemoveForwardRejectIn(server->iptables, network->bridge);
iptablesRemoveForwardRejectOut(server->iptables, network->bridge);
iptablesRemoveUdpInput(server->iptables, network->bridge, 53); iptablesRemoveUdpInput(server->iptables, network->bridge, 53);
iptablesRemoveTcpInput(server->iptables, network->bridge, 53); iptablesRemoveTcpInput(server->iptables, network->bridge, 53);
iptablesRemoveUdpInput(server->iptables, network->bridge, 67); iptablesRemoveUdpInput(server->iptables, network->bridge, 67);
iptablesRemoveTcpInput(server->iptables, network->bridge, 67); iptablesRemoveTcpInput(server->iptables, network->bridge, 67);
iptablesRemovePhysdevForward(server->iptables, network->bridge);
} }
static int static int