You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2017/05/30 22:37:26 UTC

[2/3] mesos git commit: Optionally verify the source IP address for libprocess messages.

Optionally verify the source IP address for libprocess messages.

In general, libprocess does not validate that a peer is a
legitimate owner of the UPID it claims in a libprocess message.
This change adds a check that the IP address in the UPID matches
the peer address. This makes spoofing the UPID harder (e.g. to
send authenticated messages), but also breaks some legitimate
configurations, particularly on multihomed hosts.

Review: https://reviews.apache.org/r/58224/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/8fbbebfb
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/8fbbebfb
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/8fbbebfb

Branch: refs/heads/master
Commit: 8fbbebfb66e2bc408377031f82c060500be24b19
Parents: 72b7762
Author: James Peach <jp...@apache.org>
Authored: Tue May 30 15:18:17 2017 -0700
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Tue May 30 15:34:43 2017 -0700

----------------------------------------------------------------------
 3rdparty/libprocess/src/process.cpp | 46 ++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/8fbbebfb/3rdparty/libprocess/src/process.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/process.cpp b/3rdparty/libprocess/src/process.cpp
index 3d1fba0..4e60231 100644
--- a/3rdparty/libprocess/src/process.cpp
+++ b/3rdparty/libprocess/src/process.cpp
@@ -135,6 +135,8 @@ using process::http::authentication::AuthenticatorManager;
 
 using process::http::authorization::AuthorizationCallbacks;
 
+namespace inet = process::network::inet;
+
 using process::network::inet::Address;
 using process::network::inet::Socket;
 
@@ -211,12 +213,27 @@ struct Flags : public virtual flags::FlagsBase
 
           return None();
         });
+
+    add(&Flags::require_peer_address_ip_match,
+        "require_peer_address_ip_match",
+        "If set, the IP address portion of the libprocess UPID in\n"
+        "incoming messages is required to match the IP address of\n"
+        "the socket from which the message was sent. This can be a\n"
+        "security enhancement since it prevents unauthorized senders\n"
+        "impersonating other libprocess actors. This check may\n"
+        "break configurations that require setting LIBPROCESS_IP,\n"
+        "or LIBPROCESS_ADVERTISE_IP. Additionally, multi-homed\n"
+        "configurations may be affected since the address on which\n"
+        "libprocess is listening may not match the address from\n"
+        "which libprocess connects to other actors.\n",
+        false);
   }
 
   Option<net::IP> ip;
   Option<net::IP> advertise_ip;
   Option<int> port;
   Option<int> advertise_port;
+  bool require_peer_address_ip_match;
 };
 
 } // namespace internal {
@@ -2855,6 +2872,35 @@ void ProcessManager::handle(
 
         Message* message = CHECK_NOTNULL(future.get());
 
+        // Verify that the UPID this peer is claiming is on the same IP
+        // address the peer is sending from.
+        if (flags->require_peer_address_ip_match) {
+          CHECK_SOME(request->client);
+
+          // If the client address is not an IP address (e.g. coming
+          // from a domain socket), we also reject the message.
+          Try<inet::Address> client_ip_address =
+            network::convert<inet::Address>(request->client.get());
+
+          if (client_ip_address.isError() ||
+              message->from.address.ip != client_ip_address->ip) {
+            Response response = BadRequest(
+                "UPID IP address validation failed: Message from " +
+                stringify(message->from) + " was sent from IP " +
+                stringify(request->client.get()));
+
+            dispatch(proxy, &HttpProxy::enqueue, response, *request);
+
+            VLOG(1) << "Returning '" << response.status << "'"
+                    << " for '" << request->url.path << "'"
+                    << ": " << response.body;
+
+            delete request;
+            delete message;
+            return;
+          }
+        }
+
         // TODO(benh): Use the sender PID when delivering in order to
         // capture happens-before timing relationships for testing.
         bool accepted = deliver(message->to, new MessageEvent(message));