Merge pull request #15601 from liewegas/wip-no-restful-cert

mgr: remove default cert; disable both restful and dashboard by default

Reviewed-by: Boris Ranto <branto@redhat.com>
This commit is contained in:
Sage Weil 2017-06-21 21:10:35 -05:00 committed by GitHub
commit 8d8f2c3dc3
7 changed files with 100 additions and 33 deletions

View File

@ -325,13 +325,14 @@ Requires: ceph-base = %{_epoch_prefix}%{version}-%{release}
%if 0%{?fedora} || 0%{?rhel}
Requires: python-cherrypy
Requires: python-werkzeug
Requires: pyOpenSSL
%endif
%if 0%{?suse_version}
Requires: python-CherryPy
Requires: python-Werkzeug
Requires: python-pyOpenSSL
%endif
Requires: python-pecan
Requires(post): openssl
%description mgr
ceph-mgr enables python modules that provide services (such as the REST
module derived from Calamari) and expose CLI hooks. ceph-mgr gathers
@ -1182,13 +1183,6 @@ fi
%attr(750,ceph,ceph) %dir %{_localstatedir}/lib/ceph/mgr
%post mgr
CERT="%{_sysconfdir}/ceph/ceph-mgr-restful.crt"
PKEY="%{_sysconfdir}/ceph/ceph-mgr-restful.key"
if [ ! -e "$CERT" -o ! -e "$PKEY" ]; then
openssl req -new -nodes -x509 \
-subj "/O=IT/CN=ceph-mgr-restful" \
-days 3650 -keyout "$PKEY" -out "$CERT" -extensions v3_ca
fi
%if 0%{?suse_version}
if [ $1 -eq 1 ] ; then
/usr/bin/systemctl preset ceph-mgr@\*.service ceph-mgr.target >/dev/null 2>&1 || :

View File

@ -24,13 +24,6 @@ set -e
case "$1" in
configure)
CERT="/etc/ceph/ceph-mgr-restful.crt"
PKEY="/etc/ceph/ceph-mgr-restful.key"
if [ ! -e "$CERT" -o ! -e "$PKEY" ]; then
openssl req -new -nodes -x509 \
-subj "/O=IT/CN=ceph-mgr-restful" \
-days 3650 -keyout "$PKEY" -out "$CERT" -extensions v3_ca
fi
[ -x /sbin/start ] && start ceph-mgr-all || :
if ! dpkg-statoverride --list /var/lib/ceph/mgr >/dev/null

2
debian/control vendored
View File

@ -161,9 +161,9 @@ Description: debugging symbols for ceph-mds
Package: ceph-mgr
Architecture: linux-any
Depends: ceph-base (= ${binary:Version}),
python-openssl,
python-pecan,
python-werkzeug,
openssl,
${misc:Depends},
${python:Depends},
python-cherrypy3,

View File

@ -8,6 +8,7 @@ tasks:
- ceph config-key put mgr/restful/x/server_addr 127.0.0.1
- ceph config-key put mgr/restful/x/server_port 9999
- ceph tell mgr.x restful create-key admin
- ceph tell mgr.x restful create-self-signed-cert
- ceph.restart: [mgr.x]
- workunit:
clients:

View File

@ -732,8 +732,10 @@ class Module(MgrModule):
return dict(result)
server_addr = self.get_localized_config('server_addr') or '127.0.0.1'
server_addr = self.get_localized_config('server_addr')
server_port = self.get_localized_config('server_port') or '7000'
if server_addr is None:
raise RuntimeError('no server_addr configured; try "ceph config-key put mgr/dashboard/server_addr <ip>"')
log.info("server_addr: %s server_port: %s" % (server_addr, server_port))
cherrypy.config.update({
'server.socket_host': server_addr,

View File

@ -15,6 +15,7 @@ import common
from uuid import uuid4
from pecan import jsonify, make_app
from OpenSSL import crypto
from pecan.rest import RestController
from werkzeug.serving import make_server, make_ssl_devcert
@ -212,6 +213,16 @@ class Module(MgrModule):
"desc": "List all API keys",
"perm": "rw"
},
{
"cmd": "restful create-self-signed-cert",
"desc": "Create localized self signed certificate",
"perm": "rw"
},
{
"cmd": "restful restart",
"desc": "Restart API server",
"perm": "rw"
},
]
def __init__(self, *args, **kwargs):
@ -227,12 +238,21 @@ class Module(MgrModule):
self.server = None
self.stop_server = False
self.serve_event = threading.Event()
def serve(self):
try:
self._serve()
except:
self.log.error(str(traceback.format_exc()))
while not self.stop_server:
try:
self._serve()
self.server.socket.close()
except:
self.log.error(str(traceback.format_exc()))
# Wait and clear the threading event
self.serve_event.wait()
self.serve_event.clear()
def get_localized_config(self, key):
r = self.get_config(self.get_mgr_id() + '/' + key)
@ -256,7 +276,9 @@ class Module(MgrModule):
separators=(',', ': '),
)
server_addr = self.get_localized_config('server_addr') or '127.0.0.1'
server_addr = self.get_localized_config('server_addr')
if server_addr is None:
raise RuntimeError('no server_addr configured; try "ceph config-key put mgr/restful/server_addr <ip>"')
server_port = int(self.get_localized_config('server_port') or '8003')
self.log.info('server_addr: %s server_port: %d',
server_addr, server_port)
@ -268,7 +290,7 @@ class Module(MgrModule):
cert_tmp.flush()
cert_fname = cert_tmp.name
else:
cert_fname = self.get_localized_config('crt_file') or '/etc/ceph/ceph-mgr-restful.crt'
cert_fname = self.get_localized_config('crt_file')
pkey = self.get_localized_config("key")
if pkey is not None:
@ -277,7 +299,14 @@ class Module(MgrModule):
pkey_tmp.flush()
pkey_fname = pkey_tmp.name
else:
pkey_fname = self.get_localized_config('key_file') or '/etc/ceph/ceph-mgr-restful.key'
pkey_fname = self.get_localized_config('key_file')
if not cert_fname or not pkey_fname:
raise RuntimeError('no certificate configured')
if not os.path.isfile(cert_fname):
raise RuntimeError('certificate %s does not exist' % cert_fname)
if not os.path.isfile(pkey_fname):
raise RuntimeError('private key %s does not exist' % pkey_fname)
# Create the HTTPS werkzeug server serving pecan app
self.server = make_server(
@ -295,8 +324,20 @@ class Module(MgrModule):
def shutdown(self):
try:
self.stop_server = True
if self.server:
self.server.shutdown()
self.serve_event.set()
except:
self.log.error(str(traceback.format_exc()))
raise
def restart(self):
try:
if self.server:
self.server.shutdown()
self.serve_event.set()
except:
self.log.error(str(traceback.format_exc()))
@ -330,6 +371,28 @@ class Module(MgrModule):
self.log.debug("Unhandled notification type '%s'" % notify_type)
def create_self_signed_cert(self):
# create a key pair
pkey = crypto.PKey()
pkey.generate_key(crypto.TYPE_RSA, 2048)
# create a self-signed cert
cert = crypto.X509()
cert.get_subject().O = "IT"
cert.get_subject().CN = "ceph-restful"
cert.set_serial_number(int(uuid4()))
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(10*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(pkey)
cert.sign(pkey, 'sha512')
return (
crypto.dump_certificate(crypto.FILETYPE_PEM, cert),
crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
)
def handle_command(self, command):
self.log.warn("Handling command: '%s'" % str(command))
if command['prefix'] == "restful create-key":
@ -366,6 +429,27 @@ class Module(MgrModule):
"",
)
elif command['prefix'] == "restful create-self-signed-cert":
cert, pkey = self.create_self_signed_cert()
self.set_config(self.get_mgr_id() + '/crt', cert)
self.set_config(self.get_mgr_id() + '/key', pkey)
self.restart()
return (
0,
"Restarting RESTful API server...",
""
)
elif command['prefix'] == 'restful restart':
self.restart();
return (
0,
"Restarting RESTful API server...",
""
)
else:
return (
-errno.EINVAL,

View File

@ -639,16 +639,8 @@ EOF
DASH_URLS+="http://$IP:$MGR_PORT/"
MGR_PORT=$(($MGR_PORT + 1000))
CERT=`mktemp`
PKEY=`mktemp`
openssl req -new -nodes -x509 \
-subj "/O=IT/CN=ceph-mgr-restful" \
-days 3650 -keyout "$PKEY" -out "$CERT" -extensions v3_ca
ceph_adm config-key put mgr/restful/$name/server_addr $IP
ceph_adm config-key put mgr/restful/$name/server_port $MGR_PORT
ceph_adm config-key put mgr/restful/$name/crt -i $CERT
ceph_adm config-key put mgr/restful/$name/key -i $PKEY
rm $CERT $PKEY
RESTFUL_URLS+="https://$IP:$MGR_PORT"
MGR_PORT=$(($MGR_PORT + 1000))
@ -658,7 +650,8 @@ EOF
done
SF=`mktemp`
ceph_adm tell mgr.x restful create-key admin -o $SF
ceph_adm tell mgr restful create-self-signed-cert
ceph_adm tell mgr restful create-key admin -o $SF
RESTFUL_SECRET=`cat $SF`
rm $SF
}