Code

conf2http can now use SSL!
authorSven Velt <sven@velt.de>
Tue, 9 Feb 2010 14:03:05 +0000 (15:03 +0100)
committerSven Velt <sven@velt.de>
Tue, 9 Feb 2010 14:18:35 +0000 (15:18 +0100)
Have a look at the conf2http.cfg! It *needs* two more options, "ssl" and
"sslcert". To be sure use a *FULL* pathname to key/cert file.

Create a key and self-signed certificate with:

% openssl req -x509 -nodes -days 365 -newkey rsa:1024 \
          -keyout server.pem -out server.pem

init.d/nagixsc_conf2http [new file with mode: 0755]
nagixsc.py
nagixsc_conf2http.py
sample-configs/conf2http.cfg

diff --git a/init.d/nagixsc_conf2http b/init.d/nagixsc_conf2http
new file mode 100755 (executable)
index 0000000..0a05158
--- /dev/null
@@ -0,0 +1,104 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides:          nagixsc_conf2http
+# Required-Start:    $local_fs $remote_fs
+# Required-Stop:     $local_fs $remote_fs
+# Default-Start:     2 3 4 5
+# Default-Stop:      S 0 1 6
+# Short-Description: Nag(IX)SC HTTP Pull
+# Description:       Nag(IX)SC HTTP Pull
+### END INIT INFO
+
+# Author: Sven Velt <sv@teamix.net>
+
+# PATH should only include /usr/* if it runs after the mountnfs.sh script
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+DESC="Nag(IX)SC Conf2HTTP"
+NAME=nagixsc_conf2http
+DAEMONPATH=/etc/nagios/nagixsc
+DAEMON=$DAEMONPATH/$NAME.py
+DAEMON_ARGS="-c $DAEMONPATH/etc/conf2http.cfg"
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+
+# Exit if the package is not installed
+[ -x "$DAEMON" ] || exit 0
+
+# Read configuration variable file if it is present
+# [ -r /etc/default/$NAME ] && . /etc/default/$NAME
+
+# Load the VERBOSE setting and other rcS variables
+[ -f /etc/default/rcS ] && . /etc/default/rcS
+
+# Define LSB log_* functions.
+# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
+. /lib/lsb/init-functions
+
+is_running()
+{
+       [ -f "$PIDFILE" ] || return 1
+       ps ax | grep "`cat $PIDFILE`" | grep $NAME | grep -qv grep
+       return $?
+}
+
+do_start()
+{
+       is_running && return 1
+       start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 1
+       start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $DAEMON -- $DAEMON_ARGS || return 2
+}
+
+do_stop()
+{
+       start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
+       RETVAL="$?"
+       [ "$RETVAL" = 2 ] && return 2
+       start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
+       [ "$?" = 2 ] && return 2
+       rm -f $PIDFILE
+       return "$RETVAL"
+}
+
+
+
+case "$1" in
+  start)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
+       do_start
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  stop)
+       [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
+       do_stop
+       case "$?" in
+               0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
+               2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
+       esac
+       ;;
+  restart|force-reload)
+       log_daemon_msg "Restarting $DESC" "$NAME"
+       do_stop
+       case "$?" in
+         0|1)
+               do_start
+               case "$?" in
+                       0) log_end_msg 0 ;;
+                       1) log_end_msg 1 ;; # Old process is still running
+                       *) log_end_msg 1 ;; # Failed to start
+               esac
+               ;;
+         *)
+               # Failed to stop
+               log_end_msg 1
+               ;;
+       esac
+       ;;
+  *)
+       echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
+       exit 3
+       ;;
+esac
+
index be3613d8d57ead1a9907bd52ed4bcb17516d8907..21d2b0c1b9e5b5f46e400674e3e6ac65489b2891 100644 (file)
@@ -1,8 +1,11 @@
+import BaseHTTPServer
 import ConfigParser
+import SocketServer
 import base64
 import datetime
 import libxml2
 import shlex
+import socket
 import subprocess
 import sys
 
@@ -297,3 +300,36 @@ def reset_future_timestamp(timestamp, now):
        else:
                return now
 
+##############################################################################
+
+class MyHTTPServer(BaseHTTPServer.HTTPServer):
+       def __init__(self, server_address, HandlerClass, ssl=False, sslpemfile=None):
+               if ssl:
+                       # FIXME: SSL is in Py2.6
+                       try:
+                               from OpenSSL import SSL
+                       except:
+                               print 'No Python OpenSSL wrapper/bindings found!'
+                               sys.exit(127)
+
+                       SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
+                       context = SSL.Context(SSL.SSLv23_METHOD)
+                       context.use_privatekey_file (sslpemfile)
+                       context.use_certificate_file(sslpemfile)
+                       self.socket = SSL.Connection(context, socket.socket(self.address_family, self.socket_type))
+               else:
+                       SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
+                       self.socket = socket.socket(self.address_family, self.socket_type)
+
+               self.server_bind()
+               self.server_activate()
+
+
+class MyHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+       def setup(self):
+               self.connection = self.request
+               self.rfile = socket._fileobject(self.request, "rb", self.rbufsize)
+               self.wfile = socket._fileobject(self.request, "wb", self.wbufsize)
+
+##############################################################################
+
index 640539fc98013311286c65ead7f022575501e282..d296bfff07bd2ca70da64fdd8e5ef3a1bbbccf2b 100755 (executable)
@@ -1,6 +1,5 @@
 #!/usr/bin/python
 
-import BaseHTTPServer
 import ConfigParser
 import base64
 import optparse
@@ -40,9 +39,10 @@ config = {}
 try:
        config['ip']   = cfgread.get('server', 'ip')
        config['port'] = cfgread.getint('server', 'port')
+       config['ssl']  = cfgread.getboolean('server', 'ssl')
+       config['cert'] = cfgread.get('server', 'sslcert')
 
        config['conf_dir']         = cfgread.get('server', 'conf_dir')
-       config['conf2xml_cmdline'] = cfgread.get('server', 'conf2xml_cmdline')
 
 except ConfigParser.NoOptionError, e:
        print 'Config file error: %s ' % e
@@ -54,7 +54,7 @@ for u in cfgread.options('users'):
 
 ##############################################################################
 
-class Conf2HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+class Conf2HTTPHandler(MyHTTPRequestHandler):
 
        def http_error(self, code, output):
                self.send_response(code)
@@ -65,8 +65,6 @@ class Conf2HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
 
 
        def do_GET(self):
-               cmdline = config['conf2xml_cmdline']
-
                path = self.path.split('/')
 
                # Check Basic Auth
@@ -126,8 +124,12 @@ class Conf2HTTPHandler(BaseHTTPServer.BaseHTTPRequestHandler):
 
 
 def main():
+       if config['ssl'] and not os.path.isfile(config['cert']):
+               print 'SSL certificate "%s" not found!' % config['cert']
+               sys.exit(127)
+
+       server = MyHTTPServer((config['ip'], config['port']), Conf2HTTPHandler, ssl=config['ssl'], sslpemfile=config['cert'])
        try:
-               server = BaseHTTPServer.HTTPServer((config['ip'], config['port']), Conf2HTTPHandler)
                server.serve_forever()
        except:
                server.socket.close()
index 41458cdd4b9f97935dd1e4c1d7e6146e7b68a447..9dbb3acc1c300715b9e4378c24d2e2f63c61c7cf 100644 (file)
@@ -1,8 +1,9 @@
 [server]
 ip: 0.0.0.0
 port: 15666
+ssl: true
+sslcert: server.pem
 
-conf2xml_cmdline: ./nagixsc_conf2xml.py
 conf_dir: ./sample-configs/conf
 
 [users]