diff --git a/configure.ac b/configure.ac index b6080c2345..c507891feb 100644 --- a/configure.ac +++ b/configure.ac @@ -312,6 +312,9 @@ AC_DEFINE_UNQUOTED([IP_PATH], "$IP_PATH", [path to ip binary]) AC_PATH_PROG([IPTABLES_PATH], [iptables], /sbin/iptables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([IPTABLES_PATH], "$IPTABLES_PATH", [path to iptables binary]) +AC_PATH_PROG([IP6TABLES_PATH], [ip6tables], /sbin/ip6tables, [/usr/sbin:$PATH]) +AC_DEFINE_UNQUOTED([IP6TABLES_PATH], "$IP6TABLES_PATH", [path to ip6tables binary]) + AC_PATH_PROG([EBTABLES_PATH], [ebtables], /sbin/ebtables, [/usr/sbin:$PATH]) AC_DEFINE_UNQUOTED([EBTABLES_PATH], "$EBTABLES_PATH", [path to ebtables binary]) diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c index bd0e0028fb..0c37eb6101 100644 --- a/src/network/bridge_driver.c +++ b/src/network/bridge_driver.c @@ -842,14 +842,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver, /* allow DHCP requests through to dnsmasq */ - if (iptablesAddTcpInput(driver->iptables, network->def->bridge, 67) < 0) { + if (iptablesAddTcpInput(driver->iptables, AF_INET, + network->def->bridge, 67) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s'"), network->def->bridge); goto err1; } - if (iptablesAddUdpInput(driver->iptables, network->def->bridge, 67) < 0) { + if (iptablesAddUdpInput(driver->iptables, AF_INET, + network->def->bridge, 67) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow DHCP requests from '%s'"), network->def->bridge); @@ -871,14 +873,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver, } /* allow DNS requests through to dnsmasq */ - if (iptablesAddTcpInput(driver->iptables, network->def->bridge, 53) < 0) { + if (iptablesAddTcpInput(driver->iptables, AF_INET, + network->def->bridge, 53) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow DNS requests from '%s'"), network->def->bridge); goto err3; } - if (iptablesAddUdpInput(driver->iptables, network->def->bridge, 53) < 0) { + if (iptablesAddUdpInput(driver->iptables, AF_INET, + network->def->bridge, 53) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow DNS requests from '%s'"), network->def->bridge); @@ -887,7 +891,8 @@ networkAddGeneralIptablesRules(struct network_driver *driver, /* allow TFTP requests through to dnsmasq if necessary */ if (ipv4def && ipv4def->tftproot && - iptablesAddUdpInput(driver->iptables, network->def->bridge, 69) < 0) { + iptablesAddUdpInput(driver->iptables, AF_INET, + network->def->bridge, 69) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow TFTP requests from '%s'"), network->def->bridge); @@ -896,14 +901,16 @@ networkAddGeneralIptablesRules(struct network_driver *driver, /* Catch all rules to block forwarding to/from bridges */ - if (iptablesAddForwardRejectOut(driver->iptables, network->def->bridge) < 0) { + if (iptablesAddForwardRejectOut(driver->iptables, AF_INET, + network->def->bridge) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to block outbound traffic from '%s'"), network->def->bridge); goto err6; } - if (iptablesAddForwardRejectIn(driver->iptables, network->def->bridge) < 0) { + if (iptablesAddForwardRejectIn(driver->iptables, AF_INET, + network->def->bridge) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to block inbound traffic to '%s'"), network->def->bridge); @@ -911,7 +918,8 @@ networkAddGeneralIptablesRules(struct network_driver *driver, } /* Allow traffic between guests on the same bridge */ - if (iptablesAddForwardAllowCross(driver->iptables, network->def->bridge) < 0) { + if (iptablesAddForwardAllowCross(driver->iptables, AF_INET, + network->def->bridge) < 0) { networkReportError(VIR_ERR_SYSTEM_ERROR, _("failed to add iptables rule to allow cross bridge traffic on '%s'"), network->def->bridge); @@ -922,21 +930,21 @@ networkAddGeneralIptablesRules(struct network_driver *driver, /* unwind in reverse order from the point of failure */ err8: - iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectIn(driver->iptables, AF_INET, network->def->bridge); err7: - iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge); + iptablesRemoveForwardRejectOut(driver->iptables, AF_INET, network->def->bridge); err6: if (ipv4def && ipv4def->tftproot) { - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 69); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 69); } err5: - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 53); err4: - iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 53); err3: - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 67); err2: - iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 67); err1: return -1; } @@ -955,20 +963,20 @@ networkRemoveGeneralIptablesRules(struct network_driver *driver, break; } - iptablesRemoveForwardAllowCross(driver->iptables, network->def->bridge); - iptablesRemoveForwardRejectIn(driver->iptables, network->def->bridge); - iptablesRemoveForwardRejectOut(driver->iptables, network->def->bridge); + iptablesRemoveForwardAllowCross(driver->iptables, AF_INET, network->def->bridge); + iptablesRemoveForwardRejectIn(driver->iptables, AF_INET, network->def->bridge); + iptablesRemoveForwardRejectOut(driver->iptables, AF_INET, network->def->bridge); if (ipv4def && ipv4def->tftproot) { - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 69); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 69); } - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 53); - iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 53); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 53); + iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 53); if (ipv4def && (ipv4def->nranges || ipv4def->nhosts)) { iptablesRemoveOutputFixUdpChecksum(driver->iptables, network->def->bridge, 68); } - iptablesRemoveUdpInput(driver->iptables, network->def->bridge, 67); - iptablesRemoveTcpInput(driver->iptables, network->def->bridge, 67); + iptablesRemoveUdpInput(driver->iptables, AF_INET, network->def->bridge, 67); + iptablesRemoveTcpInput(driver->iptables, AF_INET, network->def->bridge, 67); } static int diff --git a/src/util/iptables.c b/src/util/iptables.c index f7b692c76b..647e7aed6d 100644 --- a/src/util/iptables.c +++ b/src/util/iptables.c @@ -99,14 +99,17 @@ iptRulesNew(const char *table, } static int ATTRIBUTE_SENTINEL -iptablesAddRemoveRule(iptRules *rules, int action, const char *arg, ...) +iptablesAddRemoveRule(iptRules *rules, int family, int action, + const char *arg, ...) { va_list args; int ret; virCommandPtr cmd; const char *s; - cmd = virCommandNew(IPTABLES_PATH); + cmd = virCommandNew((family == AF_INET6) + ? IP6TABLES_PATH : IPTABLES_PATH); + virCommandAddArgList(cmd, "--table", rules->table, action == ADD ? "--insert" : "--delete", rules->chain, arg, NULL); @@ -177,6 +180,7 @@ iptablesContextFree(iptablesContext *ctx) static int iptablesInput(iptablesContext *ctx, + int family, const char *iface, int port, int action, @@ -188,6 +192,7 @@ iptablesInput(iptablesContext *ctx, portstr[sizeof(portstr) - 1] = '\0'; return iptablesAddRemoveRule(ctx->input_filter, + family, action, "--in-interface", iface, "--protocol", tcp ? "tcp" : "udp", @@ -210,10 +215,11 @@ iptablesInput(iptablesContext *ctx, int iptablesAddTcpInput(iptablesContext *ctx, + int family, const char *iface, int port) { - return iptablesInput(ctx, iface, port, ADD, 1); + return iptablesInput(ctx, family, iface, port, ADD, 1); } /** @@ -229,10 +235,11 @@ iptablesAddTcpInput(iptablesContext *ctx, */ int iptablesRemoveTcpInput(iptablesContext *ctx, + int family, const char *iface, int port) { - return iptablesInput(ctx, iface, port, REMOVE, 1); + return iptablesInput(ctx, family, iface, port, REMOVE, 1); } /** @@ -249,10 +256,11 @@ iptablesRemoveTcpInput(iptablesContext *ctx, int iptablesAddUdpInput(iptablesContext *ctx, + int family, const char *iface, int port) { - return iptablesInput(ctx, iface, port, ADD, 0); + return iptablesInput(ctx, family, iface, port, ADD, 0); } /** @@ -268,10 +276,11 @@ iptablesAddUdpInput(iptablesContext *ctx, */ int iptablesRemoveUdpInput(iptablesContext *ctx, + int family, const char *iface, int port) { - return iptablesInput(ctx, iface, port, REMOVE, 0); + return iptablesInput(ctx, family, iface, port, REMOVE, 0); } @@ -282,9 +291,10 @@ static char *iptablesFormatNetwork(virSocketAddr *netaddr, char *netstr; char *ret; - if (!VIR_SOCKET_IS_FAMILY(netaddr, AF_INET)) { + if (!(VIR_SOCKET_IS_FAMILY(netaddr, AF_INET) || + VIR_SOCKET_IS_FAMILY(netaddr, AF_INET6))) { iptablesError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("Only IPv4 addresses can be used with iptables")); + _("Only IPv4 or IPv6 addresses can be used with iptables")); return NULL; } @@ -327,6 +337,7 @@ iptablesForwardAllowOut(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -335,6 +346,7 @@ iptablesForwardAllowOut(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "--in-interface", iface, @@ -411,6 +423,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -421,6 +434,7 @@ iptablesForwardAllowRelatedIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -497,6 +511,7 @@ iptablesForwardAllowIn(iptablesContext *ctx, if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--destination", networkstr, "--in-interface", physdev, @@ -505,6 +520,7 @@ iptablesForwardAllowIn(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->forward_filter, + VIR_SOCKET_FAMILY(netaddr), action, "--destination", networkstr, "--out-interface", iface, @@ -567,10 +583,12 @@ iptablesRemoveForwardAllowIn(iptablesContext *ctx, */ static int iptablesForwardAllowCross(iptablesContext *ctx, + int family, const char *iface, int action) { return iptablesAddRemoveRule(ctx->forward_filter, + family, action, "--in-interface", iface, "--out-interface", iface, @@ -591,8 +609,10 @@ iptablesForwardAllowCross(iptablesContext *ctx, */ int iptablesAddForwardAllowCross(iptablesContext *ctx, - const char *iface) { - return iptablesForwardAllowCross(ctx, iface, ADD); + int family, + const char *iface) +{ + return iptablesForwardAllowCross(ctx, family, iface, ADD); } /** @@ -608,8 +628,10 @@ iptablesAddForwardAllowCross(iptablesContext *ctx, */ int iptablesRemoveForwardAllowCross(iptablesContext *ctx, - const char *iface) { - return iptablesForwardAllowCross(ctx, iface, REMOVE); + int family, + const char *iface) +{ + return iptablesForwardAllowCross(ctx, family, iface, REMOVE); } @@ -618,14 +640,16 @@ iptablesRemoveForwardAllowCross(iptablesContext *ctx, */ static int iptablesForwardRejectOut(iptablesContext *ctx, + int family, const char *iface, int action) { return iptablesAddRemoveRule(ctx->forward_filter, - action, - "--in-interface", iface, - "--jump", "REJECT", - NULL); + family, + action, + "--in-interface", iface, + "--jump", "REJECT", + NULL); } /** @@ -640,9 +664,10 @@ iptablesForwardRejectOut(iptablesContext *ctx, */ int iptablesAddForwardRejectOut(iptablesContext *ctx, + int family, const char *iface) { - return iptablesForwardRejectOut(ctx, iface, ADD); + return iptablesForwardRejectOut(ctx, family, iface, ADD); } /** @@ -657,9 +682,10 @@ iptablesAddForwardRejectOut(iptablesContext *ctx, */ int iptablesRemoveForwardRejectOut(iptablesContext *ctx, + int family, const char *iface) { - return iptablesForwardRejectOut(ctx, iface, REMOVE); + return iptablesForwardRejectOut(ctx, family, iface, REMOVE); } @@ -670,10 +696,12 @@ iptablesRemoveForwardRejectOut(iptablesContext *ctx, */ static int iptablesForwardRejectIn(iptablesContext *ctx, + int family, const char *iface, int action) { return iptablesAddRemoveRule(ctx->forward_filter, + family, action, "--out-interface", iface, "--jump", "REJECT", @@ -692,9 +720,10 @@ iptablesForwardRejectIn(iptablesContext *ctx, */ int iptablesAddForwardRejectIn(iptablesContext *ctx, + int family, const char *iface) { - return iptablesForwardRejectIn(ctx, iface, ADD); + return iptablesForwardRejectIn(ctx, family, iface, ADD); } /** @@ -709,9 +738,10 @@ iptablesAddForwardRejectIn(iptablesContext *ctx, */ int iptablesRemoveForwardRejectIn(iptablesContext *ctx, + int family, const char *iface) { - return iptablesForwardRejectIn(ctx, iface, REMOVE); + return iptablesForwardRejectIn(ctx, family, iface, REMOVE); } @@ -735,6 +765,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, if (protocol && protocol[0]) { if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->nat_postrouting, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "-p", protocol, @@ -745,6 +776,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->nat_postrouting, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "-p", protocol, @@ -756,6 +788,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, } else { if (physdev && physdev[0]) { ret = iptablesAddRemoveRule(ctx->nat_postrouting, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "!", "--destination", networkstr, @@ -764,6 +797,7 @@ iptablesForwardMasquerade(iptablesContext *ctx, NULL); } else { ret = iptablesAddRemoveRule(ctx->nat_postrouting, + VIR_SOCKET_FAMILY(netaddr), action, "--source", networkstr, "!", "--destination", networkstr, @@ -834,6 +868,7 @@ iptablesOutputFixUdpChecksum(iptablesContext *ctx, portstr[sizeof(portstr) - 1] = '\0'; return iptablesAddRemoveRule(ctx->mangle_postrouting, + AF_INET, action, "--out-interface", iface, "--protocol", "udp", diff --git a/src/util/iptables.h b/src/util/iptables.h index 982acf1489..572d612fd1 100644 --- a/src/util/iptables.h +++ b/src/util/iptables.h @@ -30,16 +30,20 @@ iptablesContext *iptablesContextNew (void); void iptablesContextFree (iptablesContext *ctx); int iptablesAddTcpInput (iptablesContext *ctx, + int family, const char *iface, int port); int iptablesRemoveTcpInput (iptablesContext *ctx, + int family, const char *iface, int port); int iptablesAddUdpInput (iptablesContext *ctx, + int family, const char *iface, int port); int iptablesRemoveUdpInput (iptablesContext *ctx, + int family, const char *iface, int port); @@ -77,18 +81,24 @@ int iptablesRemoveForwardAllowIn (iptablesContext *ctx, const char *physdev); int iptablesAddForwardAllowCross (iptablesContext *ctx, + int family, const char *iface); int iptablesRemoveForwardAllowCross (iptablesContext *ctx, + int family, const char *iface); int iptablesAddForwardRejectOut (iptablesContext *ctx, + int family, const char *iface); int iptablesRemoveForwardRejectOut (iptablesContext *ctx, + int family, const char *iface); int iptablesAddForwardRejectIn (iptablesContext *ctx, + int family, const char *iface); int iptablesRemoveForwardRejectIn (iptablesContext *ctx, + int family, const char *iface); int iptablesAddForwardMasquerade (iptablesContext *ctx,