Skip to content

Commit

Permalink
wq: openssl support (cooperative-computing-lab#2733)
Browse files Browse the repository at this point in the history
* update openssl compilation flags

* Add D_SSL debug flag

* allow extra worker args in test run_local_worker

* wrap struct link with TLS

* add SSL support to wq

* add SSL support wq python bindings

* adds work_queue/test/TR_work_queue_ssl.sh

* add --ssl to work_queue_status HOST PORT

* adds --ssl to wq factory

* fix ubuntu image transport, add libssl-dev

* correctly detect openssl headers

* add CCTOOLS_EXTERNAL_LINKAGE when compiling .so targets

* export all config.mk variables from make

This makes them available in tests that themselves do a compilation
(e.g. TR_jx_merge.sh)

* adds CCTOOLS_EXTERNAL_LINKAGE to tests that need it

* detect server/client method available

* add ssl to wq manual

* comments from review

* warn about no ssl
  • Loading branch information
btovar authored Nov 16, 2021
1 parent 1909db4 commit c7673cc
Show file tree
Hide file tree
Showing 23 changed files with 740 additions and 178 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
include config.mk
# export all variables in config.mk
export

include rules.mk


CYGWINLIB = cygwin1.dll cyggcc_s-1.dll cygintl-8.dll cygreadline7.dll cygncursesw-10.dll cygiconv-2.dll cygattr-1.dll sh.exe

#set the default values for RPM_VERSION and RPM_RELEASE
Expand Down
18 changes: 15 additions & 3 deletions batch_job/src/work_queue_factory.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ static int64_t factory_timeout = 0;

struct batch_queue *queue = 0;

// Whether workers should use ssl. If using the catalog server and the manager
// announces it is using SSL, then SSL is used regardless of manual_ssl_option.
int manual_ssl_option = 0;

//Environment variables to pass along in batch_job_submit
struct jx *batch_env = NULL;

Expand Down Expand Up @@ -381,26 +385,28 @@ static int submit_worker( struct batch_queue *queue )

if(using_catalog) {
cmd = string_format(
"%s -M %s -t %d -C '%s' -d all -o worker.log %s %s %s",
"%s -M %s -t %d -C '%s' -d all -o worker.log %s %s %s %s",
worker,
submission_regex,
worker_timeout,
catalog_host,
password_file ? "-P pwfile" : "",
resource_args ? resource_args : "",
manual_ssl_option ? "--ssl" : "",
extra_worker_args ? extra_worker_args : ""
);
}
else {
cmd = string_format(
"%s %s %d -t %d -C '%s' -d all -o worker.log %s %s %s",
"%s %s %d -t %d -C '%s' -d all -o worker.log %s %s %s %s",
worker,
manager_host,
manager_port,
worker_timeout,
catalog_host,
password_file ? "-P pwfile" : "",
resource_args ? resource_args : "",
manual_ssl_option ? "--ssl" : "",
extra_worker_args ? extra_worker_args : ""
);
}
Expand Down Expand Up @@ -1083,6 +1089,7 @@ static void show_help(const char *cmd)
printf(" %-30s Enable debugging for this subsystem.\n", "-d,--debug=<subsystem>");
printf(" %-30s Send debugging to this file.\n", "-o,--debug-file=<file>");
printf(" %-30s Specify the size of the debug file.\n", "-O,--debug-file-size=<mb>");
printf(" %-30s Workers should use SSL to connect to managers. (Not needed if project names.)", "--ssl");
printf(" %-30s Show the version string.\n", "-v,--version");
printf(" %-30s Show this screen.\n", "-h,--help");

Expand Down Expand Up @@ -1149,6 +1156,7 @@ enum{ LONG_OPT_CORES = 255,
LONG_OPT_RUN_OS,
LONG_OPT_PARENT_DEATH,
LONG_OPT_PYTHON_PACKAGE,
LONG_OPT_USE_SSL
};

static const struct option long_options[] = {
Expand Down Expand Up @@ -1193,7 +1201,8 @@ static const struct option long_options[] = {
{"worker-binary", required_argument, 0, LONG_OPT_WORKER_BINARY},
{"workers-per-cycle", required_argument, 0, LONG_OPT_WORKERS_PER_CYCLE},
{"wrapper",required_argument, 0, LONG_OPT_WRAPPER},
{"wrapper-input",required_argument, 0, LONG_OPT_WRAPPER_INPUT},
{"wrapper-input",required_argument, 0, LONG_OPT_WRAPPER_INPUT},
{"ssl",no_argument, 0, LONG_OPT_USE_SSL},
{0,0,0,0}
};

Expand Down Expand Up @@ -1392,6 +1401,9 @@ int main(int argc, char *argv[])
case LONG_OPT_PARENT_DEATH:
initial_ppid = getppid();
break;
case LONG_OPT_USE_SSL:
manual_ssl_option=1;
break;
default:
show_help(argv[0]);
return EXIT_FAILURE;
Expand Down
30 changes: 28 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ config_zlib_path=yes
config_ext2fs_path=auto
config_fuse_path=auto
config_mysql_path=auto
config_openssl_path=auto
config_perl_path=auto
config_python_path=auto # for python2 or python3, version automatically detected
config_python2_path=auto
Expand All @@ -120,7 +121,6 @@ config_cvmfs_path=no
config_globus_path=no
config_irods_path=no
config_mpi_path=no
config_openssl_path=no
config_uuid_path=no
config_xrootd_path=no

Expand Down Expand Up @@ -1228,6 +1228,27 @@ then
echo "*** Couldn't find libcrypto"
openssl_avail=no
fi

if ! optional_include openssl/ssl.h HAS_OPENSSL
then
echo "*** Couldn't find openssl headers"
openssl_avail=no
fi

if [ "${openssl_avail}" = yes ]
then
openssl_ccflags="-I${openssl_path}/include"
openssl_ldflags="-L${openssl_path}/lib -lssl -lcrypto"

if ! optional_function TLS_method openssl/ssl.h HAS_TLS_method
then
if ! optional_function SSLv23_method openssl/ssl.h HAS_SSLv23_method
then
echo "*** Couldn't find openssl methods. Perhaps openssl installation is too old?"
openssl_avail=no
fi
fi
fi
fi

report_detection openssl "${openssl_avail}" "${config_openssl_path}" "${openssl_path}"
Expand Down Expand Up @@ -1628,6 +1649,10 @@ CCTOOLS_CVMFS_AVAILABLE=${cvmfs_avail}
CCTOOLS_CVMFS_LDFLAGS=${cvmfs_ldflags}
CCTOOLS_CVMFS_CCFLAGS=${cvmfs_ccflags}
CCTOOLS_OPENSSL_AVAILABLE=${openssl_avail}
CCTOOLS_OPENSSL_LDFLAGS=${openssl_ldflags}
CCTOOLS_OPENSSL_CCFLAGS=${openssl_ccflags}
CCTOOLS_EXT2FS_AVAILABLE=${ext2fs_avail}
CCTOOLS_EXT2FS_LDFLAGS=${ext2fs_ldflags}
CCTOOLS_EXT2FS_CCFLAGS=${ext2fs_ccflags}
Expand Down Expand Up @@ -1659,8 +1684,9 @@ echo "General libraries"
printf "%-15s %3s\n" curl ${curl_avail}
printf "%-15s %3s\n" ext2fs ${ext2fs_avail}
printf "%-15s %3s\n" fuse ${fuse_avail}
printf "%-15s %3s\n" readline ${readline_avail}
printf "%-15s %3s\n" "makeflow mpi" ${mpi_avail}
printf "%-15s %3s\n" openssl ${openssl_avail}
printf "%-15s %3s\n" readline ${readline_avail}

echo ""
echo "Language support:"
Expand Down
4 changes: 2 additions & 2 deletions configure.tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ int main(int argc, char **argv) {
return 0;
}
EOF
if ${CC:-gcc} .configure.tmp.c -c -o .configure.tmp.o ${compiler_options} > .configure.tmp.out 2>&1; then
if ${CC:-gcc} ${CFLAGS} .configure.tmp.c -c -o .configure.tmp.o ${compiler_options} > .configure.tmp.out 2>&1; then
echo yes
rm -f .configure.tmp.c .configure.tmp.out
return 0
Expand Down Expand Up @@ -418,7 +418,7 @@ cat > .configure.tmp.c << EOF
#include <stdlib.h>
#include <${header}>
EOF
if ${CC:-gcc} .configure.tmp.c -c -o .configure.tmp.o > .configure.tmp.out 2>&1; then
if ${CC:-gcc} ${CFLAGS} .configure.tmp.c -c -o .configure.tmp.o > .configure.tmp.out 2>&1; then
echo yes
rm -f .configure.tmp.c .configure.tmp.out
ccflags_append_define "$@"
Expand Down
66 changes: 62 additions & 4 deletions doc/manuals/work_queue/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1222,10 +1222,68 @@ API](http://ccl.cse.nd.edu/software/manuals/api/html/work__queue_8h.html).

### Security

By default, Work Queue does **not** perform any authentication, so any workers
will be able to connect to your manager, and vice versa. This may be fine for a
short running anonymous application, but is not safe for a long running
application with a public name.
By default, Work Queue does **not** perform any encryption or authentication,
so any workers will be able to connect to your manager, and vice versa. This
may be fine for a short running anonymous application, but is not safe for a
long running application with a public name.

Currently, Work Queue uses SSL to provide communication encryption, and a
password file to provide worker-manager authentication. These features can be
enabled independet of each other.


#### SSL support

Work Queue can encrypt the communication between manager and workers using SSL.
For this, you need to specify the key and certificate (in PEM format) of your
server when creating the queue.

If you do not have a key and certificate at hand, but you want the
communications to be encrypted, you can create your own key and certificate:

```sh
# Be aware that since this certificate would not be signed by any authority, it
# cannot be used to prove the identity of the server running the manager.

openssl req -x509 -newkey rsa:4096 -keyout MY_KEY.pem -out MY_CERT.pem -sha256 -days 365 -nodes
```

To activate SSL encryption, indicate the paths to the key and certificate when
creating the queue:

=== "Python"
```python
# Import the Work Queue library
import work_queue as wq

q = wq.WorkQueue(port=9123, ssl_key='MY_KEY.pem', ssl_cert='MY_CERT.pem')
```

=== "C"
```
/* Import the Work Queue library */
#include "work_queue.h"

/* Create a new queue listening on port 9123 */
struct work_queue *q = work_queue_ssl_create(9123, 'MY_KEY.pem', 'MY_CERT.pem');
```


If you are using a (project name)[#project-names-and-the-catalog-server] for
your queue, then the workers will be aware that the manager is using SSL and
communicate accordingly automatically. However, you are directly specifying the
address of the manager when launching the workers, then you need to add the
`--ssl` flag to the command line, as:

```sh
work_queue_worker (... other args ...) --ssl HOST PORT
work_queue_factory (... other args ...) --ssl HOST PORT
work_queue_status --ssl HOST PORT
condor_submit_workers -E'--ssl' HOST PORT
```


#### Password Files

We recommend that you enable a password for your applications. Create a file
(e.g. ` mypwfile`) that contains any password (or other long phrase) that you
Expand Down
1 change: 1 addition & 0 deletions dttools/src/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ static struct flag_info table[] = {
{"dataswarm", D_DATASWARM},
{"tlq", D_TLQ},
{"jx", D_JX},
{"ssl", D_SSL},
{"all", D_ALL},
{"time", 0}, /* backwards compatibility */
{"pid", 0}, /* backwards compatibility */
Expand Down
1 change: 1 addition & 0 deletions dttools/src/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ unless it has the flags D_NOTICE or D_FATAL. For example, a main program might
#define D_EXT (1LL<<47) /**< Debug the ext module in Parrot */
#define D_DATASWARM (1LL<<48) /**< Debug the dataswarm service. */
#define D_TLQ (1LL<<49) /**< Debug the TLQ service's interactions with CCTools. */
#define D_SSL (1LL<<50) /**< Debug the TLQ service's interactions with CCTools. */

/** Debug all remote I/O operations. */
#define D_REMOTE (D_HTTP|D_FTP|D_NEST|D_CHIRP|D_DCAP|D_RFIO|D_LFC|D_GFAL|D_MULTI|D_GROW|D_IRODS|D_HDFS|D_BXGRID|D_XROOTD|D_CVMFS)
Expand Down
Loading

0 comments on commit c7673cc

Please sign in to comment.