
From: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com> Two new config options were added in config.py.in - proxy_port and proxy_ssl_port - to allow more control in the ports that the proxy will bind. The defaults proxy ports are 8000 and 8001 (ssl) and default kimchid port is 8010. The default proxy ports were chosen to avoid editing the existing firewall configuration (now that nginx is process being exposed). Kimchid creates the proxy configuration according to user-defined parameters. server.py registers the terminate_proxy() method to a cherrypy engine that fires when the server is shut down. The SSL logic was moved to the proxy module at src/kimchi/proxy.py. Signed-off-by: Daniel Henrique Barboza <danielhb@linux.vnet.ibm.com> --- src/kimchi/config.py.in | 5 +++-- src/kimchi/server.py | 44 ++++++++++++-------------------------------- src/kimchid.in | 44 +++++++++++++++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 45 deletions(-) diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in index bddcb5c..f8a645a 100644 --- a/src/kimchi/config.py.in +++ b/src/kimchi/config.py.in @@ -231,8 +231,9 @@ def _get_config(): config = SafeConfigParser() config.add_section("server") config.set("server", "host", "0.0.0.0") - config.set("server", "port", "8000") - config.set("server", "ssl_port", "8001") + config.set("server", "port", "8010") + config.set("server", "proxy_port", "8000") + config.set("server", "proxy_ssl_port", "8001") config.set("server", "ssl_cert", "") config.set("server", "ssl_key", "") config.set("server", "environment", "development") diff --git a/src/kimchi/server.py b/src/kimchi/server.py index 0d02868..f3c192e 100644 --- a/src/kimchi/server.py +++ b/src/kimchi/server.py @@ -31,6 +31,7 @@ from kimchi import mockmodel from kimchi import vnc from kimchi.config import paths, KimchiConfig, PluginConfig from kimchi.control import sub_nodes +from kimchi.proxy import start_proxy, terminate_proxy from kimchi.root import KimchiRoot from kimchi.utils import get_enabled_plugins, import_class @@ -58,6 +59,9 @@ def set_no_cache(): class Server(object): def __init__(self, options): + # Launch reverse proxy + start_proxy(options) + make_dirs = [ os.path.dirname(os.path.abspath(options.access_log)), os.path.dirname(os.path.abspath(options.error_log)), @@ -74,15 +78,12 @@ class Server(object): cherrypy.tools.nocache = cherrypy.Tool('on_end_resource', set_no_cache) cherrypy.tools.kimchiauth = cherrypy.Tool('before_handler', auth.kimchiauth) - cherrypy.server.socket_host = options.host + # Setting host to 127.0.0.1. This makes kimchi runs + # as a localhost app, inaccessible to the outside + # directly. You must go through the proxy. + cherrypy.server.socket_host = '127.0.0.1' cherrypy.server.socket_port = options.port - - # SSL Server - try: - if options.ssl_port and options.ssl_port > 0: - self._init_ssl(options) - except AttributeError: - pass + cherrypy.config.nginx_port = options.proxy_port cherrypy.log.screen = True cherrypy.log.access_file = options.access_log @@ -137,6 +138,9 @@ class Server(object): config=self.configObj) self._load_plugins() + # Terminate proxy when cherrypy server is terminated + cherrypy.engine.subscribe('exit', terminate_proxy) + cherrypy.lib.sessions.init() def _load_plugins(self): @@ -160,30 +164,6 @@ class Server(object): continue cherrypy.tree.mount(plugin_app, script_name, plugin_config) - def _init_ssl(self, options): - ssl_server = cherrypy._cpserver.Server() - ssl_server.socket_port = options.ssl_port - ssl_server._socket_host = options.host - ssl_server.ssl_module = 'builtin' - - cert = options.ssl_cert - key = options.ssl_key - if not cert or not key: - config_dir = paths.conf_dir - cert = '%s/kimchi-cert.pem' % config_dir - key = '%s/kimchi-key.pem' % config_dir - - if not os.path.exists(cert) or not os.path.exists(key): - ssl_gen = sslcert.SSLCert() - with open(cert, "w") as f: - f.write(ssl_gen.cert_pem()) - with open(key, "w") as f: - f.write(ssl_gen.key_pem()) - - ssl_server.ssl_certificate = cert - ssl_server.ssl_private_key = key - ssl_server.subscribe() - def start(self): cherrypy.engine.start() cherrypy.engine.block() diff --git a/src/kimchid.in b/src/kimchid.in index 8b63b57..c64ba4a 100644 --- a/src/kimchid.in +++ b/src/kimchid.in @@ -16,18 +16,20 @@ # # You should have received a copy of the GNU Lesser General Public # License along with this library; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA import logging import os import sys sys.path.insert(1, '@pythondir@') +from optparse import OptionParser + import kimchi.server import kimchi.config from kimchi.config import config, paths -from optparse import OptionParser if not paths.installed: sys.path.append(paths.prefix) @@ -35,23 +37,43 @@ if not paths.installed: ACCESS_LOG = "kimchi-access.log" ERROR_LOG = "kimchi-error.log" + def main(options): + # Script must run as root or with sudo. + if not os.geteuid() == 0: + sys.exit("\nMust be root to run this script. Exiting ...\n") + host = config.get("server", "host") port = config.get("server", "port") - ssl_port = config.get("server", "ssl_port") + proxy_port = config.get("server", "proxy_port") + proxy_ssl_port = config.get("server", "proxy_ssl_port") runningEnv = config.get('server', 'environment') logDir = config.get("logging", "log_dir") logLevel = config.get("logging", "log_level") parser = OptionParser() - parser.add_option('--host', type="string", default=host, help="Hostname to listen on") - parser.add_option('--port', type="int", default=port, help="Port to listen on") - parser.add_option('--ssl-port', type="int", default=ssl_port, help="Enable a SSL server on the given port") - parser.add_option('--log-level', default=logLevel, help="Logging level") - parser.add_option('--access-log', default=os.path.join(logDir,ACCESS_LOG), help="Access log file") - parser.add_option('--error-log', default=os.path.join(logDir,ERROR_LOG), help="Error log file") - parser.add_option('--environment', default=runningEnv, help="Running environment of kimchi server") - parser.add_option('--test', action='store_true', help="Run server in mock model") + parser.add_option('--host', type="string", default=host, + help="Hostname to listen on") + parser.add_option('--port', type="int", default=port, + help="Kimchid process listen port (default %s)" % port) + parser.add_option('--proxy-port', type="int", default=proxy_port, + help="Proxy port to listen on (default %s)" % + proxy_port) + parser.add_option('--proxy-ssl-port', type="int", default=proxy_ssl_port, + help="Proxy port to enable SSL (default %s)" % + proxy_ssl_port) + parser.add_option('--log-level', default=logLevel, + help="Logging level") + parser.add_option('--access-log', + default=os.path.join(logDir, ACCESS_LOG), + help="Access log file") + parser.add_option('--error-log', + default=os.path.join(logDir, ERROR_LOG), + help="Error log file") + parser.add_option('--environment', default=runningEnv, + help="Running environment of kimchi server") + parser.add_option('--test', action='store_true', + help="Run server in mock model") (options, args) = parser.parse_args() # Add non-option arguments -- 1.8.3.1