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

Add certificates files for docker engine daemon socket TLS #44

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 44 additions & 3 deletions check_docker/check_docker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import socket
import stat
import traceback
import ssl
from collections import deque, namedtuple, UserDict, defaultdict
from concurrent import futures
from datetime import datetime, timezone
Expand All @@ -20,6 +21,7 @@
from urllib.request import AbstractHTTPHandler, HTTPHandler, HTTPSHandler, OpenerDirector, HTTPRedirectHandler, \
Request, HTTPBasicAuthHandler


logger = logging.getLogger()
__author__ = 'Tim Laurence'
__copyright__ = "Copyright 2018"
Expand All @@ -43,6 +45,7 @@
DEFAULT_HEADERS = [('Accept', 'application/vnd.docker.distribution.manifest.v2+json')]
DEFAULT_PUBLIC_REGISTRY = 'registry-1.docker.io'


# The second value is the power to raise the base to.
UNIT_ADJUSTMENTS_TEMPLATE = {
'%': 0,
Expand Down Expand Up @@ -162,11 +165,10 @@ class HeadRequest(Request):
def get_method(self):
return "HEAD"


better_urllib_get = OpenerDirector()
better_urllib_get.addheaders = DEFAULT_HEADERS.copy()
better_urllib_get.add_handler(HTTPHandler())
better_urllib_get.add_handler(HTTPSHandler())

better_urllib_get.add_handler(HTTPRedirectHandler())
better_urllib_get.add_handler(SocketFileHandler())
better_urllib_get.add_handler(Oauth2TokenAuthHandler())
Expand Down Expand Up @@ -250,9 +252,11 @@ def evaluate_numeric_thresholds(container, value, thresholds, name, short_name,
ok(results_str)



@lru_cache(maxsize=None)
def get_url(url):
logger.debug("get_url: {}".format(url))

response = better_urllib_get.open(url, timeout=timeout)
logger.debug("get_url: {} {}".format(url, response.status))
return process_urllib_response(response), response.status
Expand Down Expand Up @@ -691,6 +695,28 @@ def process_args(args):
help='Use a base of 1000 when doing calculations of KB, MB, GB, & TB')
parser.set_defaults(units_base=1024)

# TLS CA File
parser.add_argument('--cafile',
dest='cafile',
action='store',
type=str,
help='TLS CA File (ex: RootCA.pem)')

# TLS Cert File
parser.add_argument('--certfile',
dest='certfile',
action='store',
type=str,
help='TLS Cert File (ex: TLS-server.pem)')

# TLS Key File
parser.add_argument('--keyfile',
dest='keyfile',
action='store',
type=str,
help='TLS Key File (ex: Key-server.pem)')


# Connection timeout
parser.add_argument('--timeout',
dest='timeout',
Expand Down Expand Up @@ -789,15 +815,17 @@ def process_args(args):
parser.print_help()

parsed_args = parser.parse_args(args=args)

global timeout
timeout = parsed_args.timeout


global daemon
global connection_type
if parsed_args.secure_connection:
daemon = 'https://' + parsed_args.secure_connection
connection_type = 'https'

elif parsed_args.connection:
if parsed_args.connection[0] == '/':
daemon = 'socket://' + parsed_args.connection + ':'
Expand Down Expand Up @@ -836,6 +864,19 @@ def print_results():

def perform_checks(raw_args):
args = process_args(raw_args)

# Add Certificate files for secure connection:
if args.secure_connection:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
if args.cafile and args.certfile and args.keyfile:
Copy link
Owner

Choose a reason for hiding this comment

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

We should display a useful message if an incomplete set of options are specified.


if args.cafile and args.certfile and args.keyfile:
   ...use handler with context
elif allargs.cafile or args.certfile or args.keyfile:
  display error about argument usage "cafile, c, and certfile, and keyfile must be used together"
else:
  use default handler

ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
ctx.load_verify_locations(args.cafile)
ctx.load_cert_chain(certfile=args.certfile, keyfile=args.keyfile)
better_urllib_get.add_handler(HTTPSHandler(context=ctx))
elif args.connection:
better_urllib_get.add_handler(HTTPSHandler())


global parallel_executor
parallel_executor = futures.ThreadPoolExecutor(max_workers=args.threads)
Expand Down
39 changes: 38 additions & 1 deletion check_docker/check_swarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import re
import socket
import stat
import ssl
from functools import lru_cache
from http.client import HTTPConnection
from sys import argv
Expand Down Expand Up @@ -73,7 +74,7 @@ def socket_open(self, req):
better_urllib_get = OpenerDirector()
better_urllib_get.addheaders = DEFAULT_HEADERS.copy()
better_urllib_get.add_handler(HTTPHandler())
better_urllib_get.add_handler(HTTPSHandler())
#better_urllib_get.add_handler(HTTPSHandler())
better_urllib_get.add_handler(SocketFileHandler())


Expand Down Expand Up @@ -205,6 +206,28 @@ def process_args(args):
type=float,
default=DEFAULT_TIMEOUT,
help='Connection timeout in seconds. (default: %(default)s)')

# TLS CA File
parser.add_argument('--cafile',
dest='cafile',
action='store',
type=str,
help='TLS CA File (ex: RootCA.pem)')

# TLS Cert File
parser.add_argument('--certfile',
dest='certfile',
action='store',
type=str,
help='TLS Cert File (ex: TLS-server.pem)')

# TLS Key File
parser.add_argument('--keyfile',
dest='keyfile',
action='store',
type=str,
help='TLS Key File (ex: Key-server.pem)')


swarm_group = parser.add_mutually_exclusive_group(required=True)

Expand Down Expand Up @@ -264,6 +287,19 @@ def print_results():

def perform_checks(raw_args):
args = process_args(raw_args)

# Add Certificate files for secure connection:
if args.secure_connection:
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
if args.cafile and args.certfile and args.keyfile:
Copy link
Owner

Choose a reason for hiding this comment

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

See above.

ctx.verify_mode = ssl.CERT_REQUIRED
ctx.check_hostname = True
ctx.load_verify_locations(args.cafile)
ctx.load_cert_chain(certfile=args.certfile, keyfile=args.keyfile)
better_urllib_get.add_handler(HTTPSHandler(context=ctx))
elif args.connection:
better_urllib_get.add_handler(HTTPSHandler())

if socketfile_permissions_failure(args):
unknown("Cannot access docker socket file. User ID={}, socket file={}".format(os.getuid(), args.connection))
else:
Expand Down Expand Up @@ -292,3 +328,4 @@ def main():

if __name__ == '__main__':
main()