packages: igmpproxy: prevent leakage of e.g. UPnP servers to upstream
git-svn-id: svn://svn.openwrt.org/openwrt/packages@31331 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
5d1b631c72
commit
cc1aa25733
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=igmpproxy
|
||||
PKG_VERSION:=0.1
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=6
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=@SF/igmpproxy
|
||||
|
@ -0,0 +1,164 @@
|
||||
From 65f777e7f66b55239d935c1cf81bb5abc0f6c89f Mon Sep 17 00:00:00 2001
|
||||
From: Grinch <grinch79@users.sourceforge.net>
|
||||
Date: Sun, 16 Aug 2009 19:58:26 +0500
|
||||
Subject: [PATCH] Restrict igmp reports for downstream interfaces (wrt #2833339)
|
||||
|
||||
atm all igmp membership reports are forwarded to the upstream interface.
|
||||
Unfortunately some ISP Providers restrict some multicast groups (esp. those
|
||||
that are defined as local link groups and that are not supposed to be
|
||||
forwarded to the wan, i.e 224.0.0.0/24). Therefore there should be some
|
||||
kind of black oder whitelisting.
|
||||
As whitelisting can be accomplished quite easy I wrote a litte patch, which
|
||||
is attached to this request.
|
||||
---
|
||||
doc/igmpproxy.conf.5.in | 19 +++++++++++++++++++
|
||||
src/config.c | 23 ++++++++++++++++++++++-
|
||||
src/igmpproxy.h | 1 +
|
||||
src/request.c | 20 ++++++++++++++++----
|
||||
4 files changed, 58 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
|
||||
index a4ea7d0..56efa22 100644
|
||||
--- a/doc/igmpproxy.conf.5.in
|
||||
+++ b/doc/igmpproxy.conf.5.in
|
||||
@@ -116,6 +116,25 @@ This is especially useful for the upstream interface, since the source for multi
|
||||
traffic is often from a remote location. Any number of altnet parameters can be specified.
|
||||
.RE
|
||||
|
||||
+.B whitelist
|
||||
+.I networkaddr
|
||||
+.RS
|
||||
+Defines a whitelist for multicast groups. The network address must be in the following
|
||||
+format 'a.b.c.d/n'. If you want to allow one single group use a network mask of /32,
|
||||
+i.e. 'a.b.c.d/32'.
|
||||
+
|
||||
+By default all multicast groups are allowed on any downstream interface. If at least one
|
||||
+whitelist entry is defined, all igmp membership reports for not explicitly whitelisted
|
||||
+multicast groups will be ignored and therefore not be served by igmpproxy. This is especially
|
||||
+useful, if your provider does only allow a predefined set of multicast groups. These whitelists
|
||||
+are only obeyed by igmpproxy itself, they won't prevent any other igmp client running on the
|
||||
+same machine as igmpproxy from requesting 'unallowed' multicast groups.
|
||||
+
|
||||
+You may specify as many whitelist entries as needed. Although you should keep it as simple as
|
||||
+possible, as this list is parsed for every membership report and therefore this increases igmp
|
||||
+response times. Often used or large groups should be defined first, as parsing ends as soon as
|
||||
+a group matches an entry.
|
||||
+.RE
|
||||
|
||||
.SH EXAMPLE
|
||||
## Enable quickleave
|
||||
diff --git a/src/config.c b/src/config.c
|
||||
index 5a96ce0..d72619f 100644
|
||||
--- a/src/config.c
|
||||
+++ b/src/config.c
|
||||
@@ -46,6 +46,9 @@ struct vifconfig {
|
||||
|
||||
// Keep allowed nets for VIF.
|
||||
struct SubnetList* allowednets;
|
||||
+
|
||||
+ // Allowed Groups
|
||||
+ struct SubnetList* allowedgroups;
|
||||
|
||||
// Next config in list...
|
||||
struct vifconfig* next;
|
||||
@@ -202,6 +205,8 @@ void configureVifs() {
|
||||
// Insert the configured nets...
|
||||
vifLast->next = confPtr->allowednets;
|
||||
|
||||
+ Dp->allowedgroups = confPtr->allowedgroups;
|
||||
+
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -215,7 +220,7 @@ void configureVifs() {
|
||||
*/
|
||||
struct vifconfig *parsePhyintToken() {
|
||||
struct vifconfig *tmpPtr;
|
||||
- struct SubnetList **anetPtr;
|
||||
+ struct SubnetList **anetPtr, **agrpPtr;
|
||||
char *token;
|
||||
short parseError = 0;
|
||||
|
||||
@@ -239,6 +244,7 @@ struct vifconfig *parsePhyintToken() {
|
||||
tmpPtr->threshold = 1;
|
||||
tmpPtr->state = IF_STATE_DOWNSTREAM;
|
||||
tmpPtr->allowednets = NULL;
|
||||
+ tmpPtr->allowedgroups = NULL;
|
||||
|
||||
// Make a copy of the token to store the IF name
|
||||
tmpPtr->name = strdup( token );
|
||||
@@ -248,6 +254,7 @@ struct vifconfig *parsePhyintToken() {
|
||||
|
||||
// Set the altnet pointer to the allowednets pointer.
|
||||
anetPtr = &tmpPtr->allowednets;
|
||||
+ agrpPtr = &tmpPtr->allowedgroups;
|
||||
|
||||
// Parse the rest of the config..
|
||||
token = nextConfigToken();
|
||||
@@ -266,6 +273,20 @@ struct vifconfig *parsePhyintToken() {
|
||||
anetPtr = &(*anetPtr)->next;
|
||||
}
|
||||
}
|
||||
+ else if(strcmp("whitelist", token)==0) {
|
||||
+ // Whitelist
|
||||
+ token = nextConfigToken();
|
||||
+ my_log(LOG_DEBUG, 0, "Config: IF: Got whitelist token %s.", token);
|
||||
+
|
||||
+ *agrpPtr = parseSubnetAddress(token);
|
||||
+ if(*agrpPtr == NULL) {
|
||||
+ parseError = 1;
|
||||
+ my_log(LOG_WARNING, 0, "Unable to parse subnet address.");
|
||||
+ break;
|
||||
+ } else {
|
||||
+ agrpPtr = &(*agrpPtr)->next;
|
||||
+ }
|
||||
+ }
|
||||
else if(strcmp("upstream", token)==0) {
|
||||
// Upstream
|
||||
my_log(LOG_DEBUG, 0, "Config: IF: Got upstream token.");
|
||||
diff --git a/src/igmpproxy.h b/src/igmpproxy.h
|
||||
index 4dabd1c..0de7791 100644
|
||||
--- a/src/igmpproxy.h
|
||||
+++ b/src/igmpproxy.h
|
||||
@@ -145,6 +145,7 @@ struct IfDesc {
|
||||
short Flags;
|
||||
short state;
|
||||
struct SubnetList* allowednets;
|
||||
+ struct SubnetList* allowedgroups;
|
||||
unsigned int robustness;
|
||||
unsigned char threshold; /* ttl limit */
|
||||
unsigned int ratelimit;
|
||||
diff --git a/src/request.c b/src/request.c
|
||||
index e3589f6..89b91de 100644
|
||||
--- a/src/request.c
|
||||
+++ b/src/request.c
|
||||
@@ -82,10 +82,22 @@ void acceptGroupReport(uint32_t src, uint32_t group, uint8_t type) {
|
||||
my_log(LOG_DEBUG, 0, "Should insert group %s (from: %s) to route table. Vif Ix : %d",
|
||||
inetFmt(group,s1), inetFmt(src,s2), sourceVif->index);
|
||||
|
||||
- // The membership report was OK... Insert it into the route table..
|
||||
- insertRoute(group, sourceVif->index);
|
||||
-
|
||||
-
|
||||
+ // If we don't have a whitelist we insertRoute and done
|
||||
+ if(sourceVif->allowedgroups == NULL)
|
||||
+ {
|
||||
+ insertRoute(group, sourceVif->index);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Check if this Request is legit on this interface
|
||||
+ struct SubnetList *sn;
|
||||
+ for(sn = sourceVif->allowedgroups; sn != NULL; sn = sn->next)
|
||||
+ if((group & sn->subnet_mask) == sn->subnet_addr)
|
||||
+ {
|
||||
+ // The membership report was OK... Insert it into the route table..
|
||||
+ insertRoute(group, sourceVif->index);
|
||||
+ return;
|
||||
+ }
|
||||
+ my_log(LOG_INFO, 0, "The group address %s may not be requested from this interface. Ignoring.", inetFmt(group, s1));
|
||||
} else {
|
||||
// Log the state of the interface the report was recieved on.
|
||||
my_log(LOG_INFO, 0, "Mebership report was recieved on %s. Ignoring.",
|
||||
--
|
||||
1.7.2.5
|
||||
|
@ -0,0 +1,62 @@
|
||||
From bcd7c648e86d97263c931de53a008c9629e7797e Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Becker <stefan.becker@nokia.com>
|
||||
Date: Fri, 11 Dec 2009 21:08:57 +0200
|
||||
Subject: [PATCH] Restrict igmp reports forwarding to upstream interface
|
||||
|
||||
Utilize the new "whitelist" keyword also on the upstream interface definition.
|
||||
If specified then only whitelisted multicast groups will be forwarded upstream.
|
||||
|
||||
This can be used to avoid publishing private multicast groups to the world,
|
||||
e.g. SSDP from a UPnP server on the internal network.
|
||||
---
|
||||
doc/igmpproxy.conf.5.in | 5 +++++
|
||||
src/rttable.c | 17 +++++++++++++++++
|
||||
2 files changed, 22 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/doc/igmpproxy.conf.5.in b/doc/igmpproxy.conf.5.in
|
||||
index 56efa22..d916f05 100644
|
||||
--- a/doc/igmpproxy.conf.5.in
|
||||
+++ b/doc/igmpproxy.conf.5.in
|
||||
@@ -134,6 +134,11 @@ You may specify as many whitelist entries as needed. Although you should keep it
|
||||
possible, as this list is parsed for every membership report and therefore this increases igmp
|
||||
response times. Often used or large groups should be defined first, as parsing ends as soon as
|
||||
a group matches an entry.
|
||||
+
|
||||
+You may also specify whitelist entries for the upstream interface. Only igmp membership reports
|
||||
+for explicitely whitelisted multicast groups will be sent out on the upstream interface. This
|
||||
+is useful if you want to use multicast groups only between your downstream interfaces, like SSDP
|
||||
+from a UPnP server.
|
||||
.RE
|
||||
|
||||
.SH EXAMPLE
|
||||
diff --git a/src/rttable.c b/src/rttable.c
|
||||
index f0701a8..77dd791 100644
|
||||
--- a/src/rttable.c
|
||||
+++ b/src/rttable.c
|
||||
@@ -117,6 +117,23 @@ void sendJoinLeaveUpstream(struct RouteTable* route, int join) {
|
||||
my_log(LOG_ERR, 0 ,"FATAL: Unable to get Upstream IF.");
|
||||
}
|
||||
|
||||
+ // Check if there is a white list for the upstram VIF
|
||||
+ if (upstrIf->allowedgroups != NULL) {
|
||||
+ uint32_t group = route->group;
|
||||
+ struct SubnetList* sn;
|
||||
+
|
||||
+ // Check if this Request is legit to be forwarded to upstream
|
||||
+ for(sn = upstrIf->allowedgroups; sn != NULL; sn = sn->next)
|
||||
+ if((group & sn->subnet_mask) == sn->subnet_addr)
|
||||
+ // Forward is OK...
|
||||
+ break;
|
||||
+
|
||||
+ if (sn == NULL) {
|
||||
+ my_log(LOG_INFO, 0, "The group address %s may not be forwarded upstream. Ignoring.", inetFmt(group, s1));
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
// Send join or leave request...
|
||||
if(join) {
|
||||
|
||||
--
|
||||
1.7.2.5
|
||||
|
Loading…
x
Reference in New Issue
Block a user