mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-10-29 17:33:09 +00:00
Fixed up IPtables rules to be more strict
This commit is contained in:
parent
7fd0878c40
commit
19c6ddcce5
@ -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
|
||||||
|
91
qemud/conf.c
91
qemud/conf.c
@ -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;
|
||||||
|
@ -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;
|
||||||
|
209
qemud/iptables.c
209
qemud/iptables.c
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -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__ */
|
||||||
|
|
||||||
|
130
qemud/qemud.c
130
qemud/qemud.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user