From 96242018c6e9355fb083983c2118ff27ea182eba Mon Sep 17 00:00:00 2001 From: Jonathan Frank Date: Fri, 13 Feb 2015 09:59:56 -0800 Subject: [PATCH] Be able to access proxy client IP (including Lua) Summary: Pass TransportInfo object through connection setup. This allows us to pass along additional info from the setup if necessary. Test Plan: Run proxygen on my devserver listening on ipv4 and ipv6 for ports 80 and 443. Configure it to run a lua request rule with the following lines: io.stderr:write("jonlog: proxy " .. conn:getClientAddrOriginal() .. "\n") io.stderr:write("jonlog: client " .. request:getClientIPStr() .. "\n") Run haproxy also on my devserver, listening on ports 8555-8558, with each forwarding to one of the four pairs (ipv4-localhost/ipv6-localhost, 80/443) From my laptop, run curls against each of these four endpoints and make sure that we print out "127.0.0.1" as the proxy IP, and my laptop's IP as the client IP. Reviewed By: cgheorghe@fb.com Subscribers: jsedgwick, yfeldblum, trunkagent, ruibalp, bmatheny, folly-diffs@, dsp, nbm FB internal diff: D1746590 Tasks: 5688127 Signature: t1:1746590:1423695880:f647964d95636a69a00304e144aef71ee0213d28 --- folly/wangle/acceptor/Acceptor.cpp | 68 ++++++++++++++++----------- folly/wangle/acceptor/Acceptor.h | 3 +- folly/wangle/acceptor/TransportInfo.h | 6 +++ 3 files changed, 49 insertions(+), 28 deletions(-) diff --git a/folly/wangle/acceptor/Acceptor.cpp b/folly/wangle/acceptor/Acceptor.cpp index 010022ce..9345fb07 100644 --- a/folly/wangle/acceptor/Acceptor.cpp +++ b/folly/wangle/acceptor/Acceptor.cpp @@ -57,9 +57,11 @@ class AcceptorHandshakeHelper : AcceptorHandshakeHelper(AsyncSSLSocket::UniquePtr socket, Acceptor* acceptor, const SocketAddress& clientAddr, - std::chrono::steady_clock::time_point acceptTime) + std::chrono::steady_clock::time_point acceptTime, + TransportInfo& tinfo) : socket_(std::move(socket)), acceptor_(acceptor), - acceptTime_(acceptTime), clientAddr_(clientAddr) { + acceptTime_(acceptTime), clientAddr_(clientAddr), + tinfo_(tinfo) { acceptor_->downstreamConnectionManager_->addConnection(this, true); if(acceptor_->parseClientHello_) { socket_->enableClientHelloParsing(); @@ -106,36 +108,41 @@ class AcceptorHandshakeHelper : // fill in SSL-related fields from TransportInfo // the other fields like RTT are filled in the Acceptor - TransportInfo tinfo; - tinfo.ssl = true; - tinfo.acceptTime = acceptTime_; - tinfo.sslSetupTime = std::chrono::duration_cast(std::chrono::steady_clock::now() - acceptTime_); - tinfo.sslSetupBytesRead = sock->getRawBytesReceived(); - tinfo.sslSetupBytesWritten = sock->getRawBytesWritten(); - tinfo.sslServerName = sock->getSSLServerName() ? + tinfo_.ssl = true; + tinfo_.acceptTime = acceptTime_; + tinfo_.sslSetupTime = std::chrono::duration_cast( + std::chrono::steady_clock::now() - acceptTime_ + ); + tinfo_.sslSetupBytesRead = sock->getRawBytesReceived(); + tinfo_.sslSetupBytesWritten = sock->getRawBytesWritten(); + tinfo_.sslServerName = sock->getSSLServerName() ? std::make_shared(sock->getSSLServerName()) : nullptr; - tinfo.sslCipher = sock->getNegotiatedCipherName() ? + tinfo_.sslCipher = sock->getNegotiatedCipherName() ? std::make_shared(sock->getNegotiatedCipherName()) : nullptr; - tinfo.sslVersion = sock->getSSLVersion(); - tinfo.sslCertSize = sock->getSSLCertSize(); - tinfo.sslResume = SSLUtil::getResumeState(sock); - tinfo.sslClientCiphers = std::make_shared(); - sock->getSSLClientCiphers(*tinfo.sslClientCiphers); - tinfo.sslServerCiphers = std::make_shared(); - sock->getSSLServerCiphers(*tinfo.sslServerCiphers); - tinfo.sslClientComprMethods = + tinfo_.sslVersion = sock->getSSLVersion(); + tinfo_.sslCertSize = sock->getSSLCertSize(); + tinfo_.sslResume = SSLUtil::getResumeState(sock); + tinfo_.sslClientCiphers = std::make_shared(); + sock->getSSLClientCiphers(*tinfo_.sslClientCiphers); + tinfo_.sslServerCiphers = std::make_shared(); + sock->getSSLServerCiphers(*tinfo_.sslServerCiphers); + tinfo_.sslClientComprMethods = std::make_shared(sock->getSSLClientComprMethods()); - tinfo.sslClientExts = + tinfo_.sslClientExts = std::make_shared(sock->getSSLClientExts()); - tinfo.sslNextProtocol = std::make_shared(); - tinfo.sslNextProtocol->assign(reinterpret_cast(nextProto), + tinfo_.sslNextProtocol = std::make_shared(); + tinfo_.sslNextProtocol->assign(reinterpret_cast(nextProto), nextProtoLength); - acceptor_->updateSSLStats(sock, tinfo.sslSetupTime, SSLErrorEnum::NO_ERROR); + acceptor_->updateSSLStats( + sock, + tinfo_.sslSetupTime, + SSLErrorEnum::NO_ERROR + ); acceptor_->downstreamConnectionManager_->removeConnection(this); acceptor_->sslConnectionReady(std::move(socket_), clientAddr_, nextProto ? string((const char*)nextProto, nextProtoLength) : - empty_string, tinfo); + empty_string, tinfo_); delete this; } @@ -155,6 +162,7 @@ class AcceptorHandshakeHelper : Acceptor* acceptor_; std::chrono::steady_clock::time_point acceptTime_; SocketAddress clientAddr_; + TransportInfo tinfo_; SSLErrorEnum sslError_{SSLErrorEnum::NO_ERROR}; }; @@ -281,14 +289,16 @@ void Acceptor::onDoneAcceptingConnection( int fd, const SocketAddress& clientAddr, std::chrono::steady_clock::time_point acceptTime) noexcept { - processEstablishedConnection(fd, clientAddr, acceptTime); + TransportInfo tinfo; + processEstablishedConnection(fd, clientAddr, acceptTime, tinfo); } void Acceptor::processEstablishedConnection( int fd, const SocketAddress& clientAddr, - std::chrono::steady_clock::time_point acceptTime) noexcept { + std::chrono::steady_clock::time_point acceptTime, + TransportInfo& tinfo) noexcept { if (accConfig_.isSSL()) { CHECK(sslCtxManager_); AsyncSSLSocket::UniquePtr sslSock( @@ -305,9 +315,13 @@ Acceptor::processEstablishedConnection( return; } new AcceptorHandshakeHelper( - std::move(sslSock), this, clientAddr, acceptTime); + std::move(sslSock), + this, + clientAddr, + acceptTime, + tinfo + ); } else { - TransportInfo tinfo; tinfo.ssl = false; tinfo.acceptTime = acceptTime; AsyncSocket::UniquePtr sock(makeNewAsyncSocket(base_, fd)); diff --git a/folly/wangle/acceptor/Acceptor.h b/folly/wangle/acceptor/Acceptor.h index 23d8ee02..22c46719 100644 --- a/folly/wangle/acceptor/Acceptor.h +++ b/folly/wangle/acceptor/Acceptor.h @@ -170,7 +170,8 @@ class Acceptor : void processEstablishedConnection( int fd, const SocketAddress& clientAddr, - std::chrono::steady_clock::time_point acceptTime + std::chrono::steady_clock::time_point acceptTime, + TransportInfo& tinfo ) noexcept; /** diff --git a/folly/wangle/acceptor/TransportInfo.h b/folly/wangle/acceptor/TransportInfo.h index c02bac42..a3b99ca1 100644 --- a/folly/wangle/acceptor/TransportInfo.h +++ b/folly/wangle/acceptor/TransportInfo.h @@ -123,6 +123,12 @@ struct TransportInfo { */ int64_t totalBytes{0}; + /** + * If the client passed through one of our L4 proxies (using PROXY Protocol), + * then this will contain the IP address of the proxy host. + */ + std::shared_ptr clientAddrOriginal; + /** * header bytes read */ -- 2.34.1