Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wip rgw openssl 7 #11776

Merged
merged 7 commits into from Jan 6, 2017
43 changes: 42 additions & 1 deletion CMakeLists.txt
Expand Up @@ -315,7 +315,7 @@ if(USE_NSS)
else(USE_NSS)
#openssl
find_package(OpenSSL REQUIRED)
set(HAVE_OPENSSL ON)
set(USE_OPENSSL ON)
set(SSL_LIBRARIES ${OPENSSL_LIBRARIES})
message(STATUS "SSL with OpenSSL selected (Libs: ${SSL_LIBRARIES})")
endif(USE_NSS)
Expand All @@ -341,6 +341,47 @@ endif(WITH_RADOSGW)

option(WITH_RADOSGW_ASIO_FRONTEND "Rados Gateway's ASIO frontend is enabled" ON)

if (WITH_RADOSGW)
if (NOT DEFINED OPENSSL_FOUND)
message(STATUS "Looking for openssl anyways, because radosgw selected")
find_package(OpenSSL)
endif()
if (OPENSSL_FOUND)
execute_process(
COMMAND
"sh" "-c"
"objdump -p ${OPENSSL_SSL_LIBRARY} | sed -n 's/^ SONAME *//p'"
OUTPUT_VARIABLE LIBSSL_SONAME
ERROR_VARIABLE OBJDUMP_ERRORS
RESULT_VARIABLE OBJDUMP_RESULTS
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (OBJDUMP_RESULTS)
message(FATAL_ERROR "can't run objdump: ${OBJDUMP_RESULTS}")
endif()
if (NOT OBJDUMP_ERRORS STREQUAL "")
message(WARNING "message from objdump: ${OBJDUMP_ERRORS}")
endif()
execute_process(
COMMAND
"sh" "-c"
"objdump -p ${OPENSSL_CRYPTO_LIBRARY} | sed -n 's/^ SONAME *//p'"
OUTPUT_VARIABLE LIBCRYPTO_SONAME
ERROR_VARIABLE OBJDUMP_ERRORS
RESULT_VARIABLE OBJDUMP_RESULTS
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (OBJDUMP_RESULTS)
message(FATAL_ERROR "can't run objdump: ${OBJDUMP_RESULTS}")
endif()
if (NOT OBJDUMP_ERRORS STREQUAL "")
message(WARNING "message from objdump: ${OBJDUMP_ERRORS}")
endif()
message(STATUS "ssl soname: ${LIBSSL_SONAME}")
message(STATUS "crypto soname: ${LIBCRYPTO_SONAME}")
else()
message(WARNING "ssl not found: rgw civetweb may fail to dlopen libssl libcrypto")
endif()
endif (WITH_RADOSGW)

#option for CephFS
option(WITH_CEPHFS "CephFS is enabled" ON)

Expand Down
28 changes: 25 additions & 3 deletions doc/install/install-ceph-gateway.rst
Expand Up @@ -83,9 +83,8 @@ your administration server. Add a section entitled
``[client.rgw.<gateway-node>]``, replacing ``<gateway-node>`` with the short
node name of your Ceph Object Gateway node (i.e., ``hostname -s``).

.. note:: In version 0.94, the Ceph Object Gateway does not support SSL. You
may setup a reverse proxy web server with SSL to dispatch HTTPS
requests as HTTP requests to CivetWeb.
.. note:: As of version 11.0.1, the Ceph Object Gateway **does** support SSL.
See `Using SSL with Civetweb`_ for information on how to set that up.

For example, if your node name is ``gateway-node1``, add a section like this
after the ``[global]`` section::
Expand Down Expand Up @@ -145,6 +144,28 @@ execute the following as the ``root`` user::

iptables-save > /etc/iptables/rules.v4

Using SSL with Civetweb
-----------------------
.. _Using SSL with Civetweb:

Before using SSL with civetweb, you will need a certificate that will match
the host name that that will be used to access the Ceph Object Gateway.
You may wish to obtain one that has `subject alternate name` fields for
more flexibility. If you intend to use S3-style subdomains
(`Add Wildcard to DNS`_), you will need a `wildcard` certificate.

Civetweb requires that the server key, server certificate, and any other
CA or intermediate certificates be supplied in one file. Each of these
items must be in `pem` form. Because the combined file contains the
secret key, it should be protected from unauthorized access.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we clarify "unauthorized access" here? Explicitly "Only the UID that runs radosgw (the "ceph" UID) should have read access to this key file on the RGW server" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm more worried about people publishing them via the web, making them accessible company wide via puppet, or throwing printouts in the waste basket. All those "careless" things people do. So I'd rather not be too specific.


To configure ssl operation, append ``s`` to the port number. Currently
it is not possible to configure the radosgw to listen on both
http and https, you must pick only one. So::

[client.rgw.gateway-node1]
rgw_frontends = civetweb port=443s ssl_certificate=/etc/ceph/private/keyandcert.pem

Migrating from Apache to Civetweb
---------------------------------

Expand Down Expand Up @@ -267,6 +288,7 @@ Where ``client.rgw.ceph-client`` is the name of the gateway user.

Add Wildcard to DNS
-------------------
.. _Add Wildcard to DNS:

To use Ceph with S3-style subdomains (e.g., bucket-name.domain-name.com), you
need to add a wildcard to the DNS record of the DNS server you use with the
Expand Down
16 changes: 12 additions & 4 deletions src/CMakeLists.txt
Expand Up @@ -905,17 +905,25 @@ endif(WITH_KVS)
if(WITH_RADOSGW)
set(civetweb_common_files civetweb/src/civetweb.c)
add_library(civetweb_common_objs OBJECT ${civetweb_common_files})
target_include_directories(civetweb_common_objs PUBLIC
target_include_directories(civetweb_common_objs PRIVATE
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdw-at-linuxbox why is this needed? Also, please change the title and description of this commit

"${CMAKE_SOURCE_DIR}/src/civetweb/include")
set_property(TARGET civetweb_common_objs
APPEND PROPERTY COMPILE_DEFINITIONS USE_IPV6=1)
if(HAVE_SSL)
if(USE_OPENSSL)
set_property(TARGET civetweb_common_objs
APPEND PROPERTY COMPILE_DEFINITIONS NO_SSL_DL=1)
target_include_directories(civetweb_common_objs PUBLIC
target_include_directories(civetweb_common_objs PRIVATE
"${SSL_INCLUDE_DIR}")
endif(HAVE_SSL)
endif(USE_OPENSSL)
if (LIBSSL_SONAME)
set_property(TARGET civetweb_common_objs
APPEND PROPERTY COMPILE_DEFINITIONS SSL_LIB="${LIBSSL_SONAME}")
set_property(TARGET civetweb_common_objs
APPEND PROPERTY COMPILE_DEFINITIONS CRYPTO_LIB="${LIBCRYPTO_SONAME}")
endif()

add_subdirectory(rgw)

endif(WITH_RADOSGW)

install(FILES
Expand Down
2 changes: 1 addition & 1 deletion src/civetweb
Submodule civetweb updated 96 files
+8 −0 .gitattributes
+4 −0 .gitignore
+95 −4 .travis.yml
+23 −9 CMakeLists.txt
+19 −1 CREDITS.md
+3 −1 Makefile
+1 −1 Makefile.osx
+48 −21 README.md
+19 −5 RELEASE_NOTES.md
+0 −171 VS2012/civetweb.sln
+0 −0 VisualStudio/buildRelease.pl
+75 −0 VisualStudio/civetweb.sln
+0 −0 VisualStudio/civetweb/civetweb.vcxproj
+0 −0 VisualStudio/civetweb/civetweb.vcxproj.filters
+11 −41 VisualStudio/civetweb_lua/civetweb_lua.vcxproj
+3 −0 VisualStudio/civetweb_lua/civetweb_lua.vcxproj.filters
+0 −0 VisualStudio/civetweb_yassl/civetweb_yassl.sln
+0 −0 VisualStudio/civetweb_yassl/civetweb_yassl/civetweb_yassl.vcxproj
+0 −0 VisualStudio/civetweb_yassl/civetweb_yassl/civetweb_yassl.vcxproj.filters
+0 −0 VisualStudio/civetweb_yassl/yassl_lib/yassl_lib.vcxproj
+0 −0 VisualStudio/civetweb_yassl/yassl_lib/yassl_lib.vcxproj.filters
+8 −7 VisualStudio/duktape_lib/duktape_lib.vcxproj
+0 −0 VisualStudio/duktape_lib/duktape_lib.vcxproj.filters
+11 −10 VisualStudio/ex_embed_cpp/ex_embed_cpp.vcxproj
+0 −0 VisualStudio/ex_embed_cpp/ex_embed_cpp.vcxproj.filters
+11 −10 VisualStudio/ex_embedded_c/ex_embedded_c.vcxproj
+0 −0 VisualStudio/ex_embedded_c/ex_embedded_c.vcxproj.filters
+9 −7 VisualStudio/ex_websocket/ex_websocket.vcxproj
+0 −0 VisualStudio/ex_websocket/ex_websocket.vcxproj.filters
+9 −7 VisualStudio/ex_websocket_client/ex_websocket_client.vcxproj
+0 −0 VisualStudio/ex_websocket_client/ex_websocket_client.vcxproj.filters
+11 −10 VisualStudio/lua_lib/lua_lib.vcxproj
+0 −0 VisualStudio/lua_lib/lua_lib.vcxproj.filters
+7 −6 VisualStudio/unit_test/unit_test.vcxproj
+0 −0 VisualStudio/unit_test/unit_test.vcxproj.filters
+12 −11 VisualStudio/upload/upload.vcxproj
+0 −0 VisualStudio/upload/upload.vcxproj.filters
+39 −13 appveyor.yml
+31 −0 cmake/check/c82fe8888aacfe784476112edd3878256d2e30bc.patch
+14 −7 docs/Building.md
+4 −4 docs/Contribution.md
+17 −10 docs/Embedding.md
+10 −10 docs/OpenSSL.md
+35 −1 docs/UserManual.md
+7 −6 docs/yaSSL.md
+126 −52 examples/embedded_c/embedded_c.c
+9 −4 examples/embedded_cpp/embedded_cpp.cpp
+6 −0 examples/upload/upload.c
+6 −1 examples/websocket_client/websocket_client.c
+26 −2 include/CivetServer.h
+208 −11 include/civetweb.h
+8 −5 resources/coverity_check.sh
+ resources/duktape-logo.png
+15 −0 resources/mingw.bat
+5 −5 src/CMakeLists.txt
+21 −7 src/CivetServer.cpp
+884 −470 src/civetweb.c
+364 −261 src/handle_form.inl
+97 −35 src/main.c
+1 −1 src/md5.inl
+136 −4 src/mod_lua.inl
+1 −1 src/third_party/sqlite3.c
+7 −0 src/timer.inl
+4 −12 test/100images.htm
+26 −18 test/CMakeLists.txt
+2 −1 test/ajax/test.html
+40 −0 test/cgi_test.c
+12 −0 test/cgi_test.html
+93 −0 test/filehandler.lua
+5 −0 test/hello.shtml
+2 −2 test/linux.cgi
+5 −1 test/main.c
+13 −0 test/page4.lua
+173 −21 test/private.c
+3 −1 test/private_exe.c
+72 −3 test/public_func.c
+1,504 −59 test/public_server.c
+1 −1 test/shared.c
+0 −5 test/ssi1.shtml
+0 −5 test/ssi2.shtml
+0 −5 test/ssi3.shtml
+0 −5 test/ssi4.shtml
+0 −5 test/ssi5.shtml
+0 −5 test/ssi6.shtml
+0 −6 test/ssi7.shtml
+0 −1 test/ssi8.shtml
+0 −3 test/ssi9.shtml
+37 −0 test/ssi_test.shtml
+53 −62 test/unit_test.c
+0 −119 testutils/Browser/Browser.cpp
+0 −90 testutils/Browser/Browser.vcxproj
+0 −5 testutils/readme.txt
+0 −372 testutils/testclient/testclient.c
+0 −91 testutils/testclient/testclient.vcxproj
+0 −239 testutils/testclient_chunked_linux/testclient.c
+0 −91 testutils/testclient_chunked_linux/testclient2.vcxproj
20 changes: 14 additions & 6 deletions src/rgw/rgw_civetweb.cc
Expand Up @@ -29,13 +29,23 @@ size_t RGWCivetWeb::write_data(const char *buf, const size_t len)
return len;
}

RGWCivetWeb::RGWCivetWeb(mg_connection* const conn, const int port)
RGWCivetWeb::RGWCivetWeb(mg_connection* const conn)
: conn(conn),
port(port),
explicit_keepalive(false),
explicit_conn_close(false),
txbuf(*this)
{
sockaddr *lsa = mg_get_local_addr(conn);
switch(lsa->sa_family) {
case AF_INET:
port = ntohs(((struct sockaddr_in*)lsa)->sin_port);
break;
case AF_INET6:
port = ntohs(((struct sockaddr_in6*)lsa)->sin6_port);
break;
default:
port = -1;
}
}

size_t RGWCivetWeb::read_data(char *buf, size_t len)
Expand Down Expand Up @@ -110,14 +120,12 @@ void RGWCivetWeb::init_env(CephContext *cct)
env.set("REMOTE_USER", info->remote_user);
}

if (port <= 0)
lderr(cct) << "init_env: bug: invalid port number" << dendl;
char port_buf[16];
snprintf(port_buf, sizeof(port_buf), "%d", port);
env.set("SERVER_PORT", port_buf);

if (info->is_ssl) {
if (port == 0) {
strcpy(port_buf,"443");
}
env.set("SERVER_PORT_SECURE", port_buf);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rgw/rgw_civetweb.h
Expand Up @@ -52,7 +52,7 @@ class RGWCivetWeb : public rgw::io::RestfulClient,
return env;
}

RGWCivetWeb(mg_connection *_conn, int _port);
RGWCivetWeb(mg_connection *_conn);
};

#endif
7 changes: 5 additions & 2 deletions src/rgw/rgw_civetweb_frontend.cc
Expand Up @@ -22,7 +22,7 @@ int RGWCivetWebFrontend::process(struct mg_connection* const conn)
/* Hold a read lock over access to env.store for reconfiguration. */
RWLock::RLocker lock(env.mutex);

RGWCivetWeb cw_client(conn, env.port);
RGWCivetWeb cw_client(conn);
auto real_client_io = rgw::io::add_reordering(
rgw::io::add_buffering(
rgw::io::add_chunking(
Expand All @@ -45,14 +45,17 @@ int RGWCivetWebFrontend::process(struct mg_connection* const conn)
int RGWCivetWebFrontend::run()
{
auto& conf_map = conf->get_config_map();
string port_str;

set_conf_default(conf_map, "num_threads",
std::to_string(g_conf->rgw_thread_pool_size));
set_conf_default(conf_map, "decode_url", "no");
set_conf_default(conf_map, "enable_keep_alive", "yes");
conf_map["listening_ports"] = conf->get_val("port", "80");
set_conf_default(conf_map, "validate_http_method", "no");
set_conf_default(conf_map, "canonicalize_url_path", "no");
conf->get_val("port", "80", &port_str);
std::replace(port_str.begin(), port_str.end(), '+', ',');
conf_map["listening_ports"] = port_str;

/* Set run_as_user. This will cause civetweb to invoke setuid() and setgid()
* based on pw_uid and pw_gid obtained from pw_name. */
Expand Down
5 changes: 1 addition & 4 deletions src/rgw/rgw_main.cc
Expand Up @@ -187,7 +187,6 @@ static void reloader_handler(int signum)
sighup_handler(signum);
}


/*
* start up the RADOS connection and then handle HTTP messages as they come in
*/
Expand Down Expand Up @@ -470,12 +469,10 @@ int main(int argc, const char **argv)

fe = new RGWFCGXFrontend(fcgi_pe, config);
} else if (framework == "civetweb" || framework == "mongoose") {
int port;
config->get_val("port", 80, &port);
std::string uri_prefix;
config->get_val("prefix", "", &uri_prefix);

RGWProcessEnv env = { store, &rest, olog, port, uri_prefix };
RGWProcessEnv env = { store, &rest, olog, 0, uri_prefix };

fe = new RGWCivetWebFrontend(env, config);
} else if (framework == "loadgen") {
Expand Down
10 changes: 6 additions & 4 deletions src/rgw/rgw_rest_s3.cc
Expand Up @@ -3798,10 +3798,12 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b
}
string token_value = string(t);
if (force_boto2_compat && using_qs && (token == "host")) {
if (!port.empty() && port != "80" && port != "0") {
token_value = token_value + ":" + port;
} else if (!secure_port.empty() && secure_port != "443") {
token_value = token_value + ":" + secure_port;
if (!secure_port.empty()) {
if (secure_port != "443")
token_value = token_value + ":" + secure_port;
} else if (!port.empty()) {
if (port != "80")
token_value = token_value + ":" + port;
}
}
canonical_hdrs_map[token] = rgw_trim_whitespace(token_value);
Expand Down