diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/WebAppProxyServlet.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/WebAppProxyServlet.java index 19ae9dc..5802c3e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/WebAppProxyServlet.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-web-proxy/src/main/java/org/apache/hadoop/yarn/server/webproxy/WebAppProxyServlet.java @@ -23,15 +23,18 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetAddress; +import java.net.Socket; import java.net.URI; import java.net.URISyntaxException; import java.net.URLEncoder; +import java.security.GeneralSecurityException; import java.util.Arrays; import java.util.EnumSet; import java.util.Enumeration; import java.util.HashSet; import java.util.List; +import javax.net.ssl.SSLSocketFactory; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -44,9 +47,13 @@ import org.apache.commons.httpclient.cookie.CookiePolicy; import org.apache.commons.httpclient.methods.GetMethod; import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.io.IOUtils; +import org.apache.hadoop.security.ssl.SSLFactory; import org.apache.hadoop.yarn.api.records.ApplicationId; import org.apache.hadoop.yarn.api.records.ApplicationReport; import org.apache.hadoop.yarn.conf.YarnConfiguration; @@ -141,14 +148,18 @@ private static void warnUserPage(HttpServletResponse resp, String link, /** * Download link and have it be the response. + * + * * @param req the http request * @param resp the http response * @param link the link to download * @param c the cookie to set if any - * @throws IOException on any error. */ - private static void proxyLink(HttpServletRequest req, - HttpServletResponse resp, URI link, Cookie c, String proxyHost) + private void proxyLink(HttpServletRequest req, + HttpServletResponse resp, + URI link, + Cookie c, + String proxyHost) throws IOException { org.apache.commons.httpclient.URI uri = new org.apache.commons.httpclient.URI(link.toString(), false); @@ -176,6 +187,9 @@ private static void proxyLink(HttpServletRequest req, method.setRequestHeader(name, value); } } + if (YarnConfiguration.useHttps(conf)) { + configureClientForSSL(conf, uri, config); + } String user = req.getRemoteUser(); if(user != null && !user.isEmpty()) { @@ -199,7 +213,63 @@ private static void proxyLink(HttpServletRequest req, method.releaseConnection(); } } - + + /** + * Configure the HTTP client's host configuration to allow for SSL + * communication. The client is required to have an AM certificate in + * its trust store to connect to an AM host. The SSLFactory will read the + * ssl-client.xml file and load the configured trust store (which should + * contain the certificates for the cluster NM hosts). The socket factory + * retrieved from the SSLFactory is configured as the HTTPS protocol handler + * for the HTTP client. + * + * @param uri the AM URI + * @param config the HTTP client's host configuration + * @throws IOException + */ + private void configureClientForSSL(org.apache.commons.httpclient.URI uri, + HostConfiguration config) + throws IOException { + final SSLFactory sslFactory = new SSLFactory(SSLFactory.Mode.CLIENT, conf); + try { + Protocol amHttpsProtocol = new Protocol("https", + new ProtocolSocketFactory() { + SSLSocketFactory + sslSocketFactory = sslFactory.createSSLSocketFactory(); + @Override + public Socket createSocket(String host, + int port, + InetAddress localAddress, + int localPort) + throws IOException { + return sslSocketFactory.createSocket(host, port, localAddress, + localPort); + } + + @Override + public Socket createSocket(String host, + int port, + InetAddress localAddress, + int localPort, + HttpConnectionParams httpConnectionParams) + throws IOException { + return sslSocketFactory.createSocket(host, port, localAddress, + localPort); + } + + @Override + public Socket createSocket(String host, int port) + throws IOException { + return sslSocketFactory.createSocket(host, port); + } + }, uri.getPort()); + + config.setHost(uri.getHost(), uri.getPort(), amHttpsProtocol); + } catch (GeneralSecurityException e) { + throw new IOException(e); + } + } + private static String getCheckCookieName(ApplicationId id){ return "checked_"+id; }