How to Support SSL in Airflow MySQLHook (in particular AWS 2019CA) - mysql

I have been using MySQLHook happily in my Airflow DAG but now the MySQL server (AWS RDS) will have SSL connection mandatory. My backend engineer told me that in particular AWS 2019 CA should be used. I looked into the MySQLHook documentation and found the following snippet from https://airflow.readthedocs.io/en/stable/_modules/airflow/hooks/mysql_hook.html:
if conn.extra_dejson.get('ssl', False):
# SSL parameter for MySQL has to be a dictionary and in case
# of extra/dejson we can get string if extra is passed via
# URL parameters
dejson_ssl = conn.extra_dejson['ssl']
if isinstance(dejson_ssl, six.string_types):
dejson_ssl = json.loads(dejson_ssl)
conn_config['ssl'] = dejson_ssl
It looks like I need to specify some configuration in the form of JSON ("SSL" key) in the extra section of the MySQL connection in Airflow but I couldn't find any examples of this. Can someone enlighten me? Any pointer or an example of such JSON would be very appreciated.

Your Connection.extra data should be a JSON string containing a ssl object suitable for passing to the mysql_ssl_set function, according to the "Functions and attributes" section on this page:
This parameter takes a dictionary or mapping, where the keys are parameter names used by the mysql_ssl_set MySQL C API call. If this is set, it initiates an SSL connection to the server; if there is no SSL support in the client, an exception is raised. This must be a keyword parameter.
Presumably something like this would work: {"ssl": {"cert": "PATH TO YOUR PUBLIC CERT FILE ON THE AIRFLOW SERVER"}}

Related

ejabberd: How to use "ldap_tls_certfile"

According to the ejabberd docs, you can use ldap_tls_certfile in order to verify the TLS connection to the LDAP server. But which certificate is expected here?
Quoting the docs:
A path to a file containing PEM encoded certificate along with PEM
encoded private key. This certificate will be provided by ejabberd
when TLS enabled for LDAP connections. There is no default value,
which means no client certificate will be sent.
Sooo.... I tried to use a concatenated PEM file containing first the host certificate of the ejabberd server, then second the host key. But this leads to the following errors:
<0.471.0>#eldap:connect_bind:1073 LDAP connection to
ldap1.example.com:636 failed: received CLIENT ALERT: Fatal - Handshake
Failure - {bad_cert,hostname_check_failed}
<0.1975.0> TLS client: In state certify at ssl_handshake.erl:1372 generated CLIENT ALERT: Fatal - Handshake Failure - {bad_cert,hostname_check_failed}
This obviously is not what is expected. Is it the public certificate of the LDAP server? But then, what private key is expected?
I'm a bit lost here. Anyone mind to lend me a hand?
Disclaimer: I never used LDAP TLS.
Looking at the ejabberd source code, the value of ejabberd's option ldap_tls_certfile
is copied into eldap's option tls_certfile
https://github.com/processone/ejabberd/blob/e4d600729396a8539e48ac0cbd97ea1b210941cd/include/eldap.hrl#L72
And later the value of eldap's tls_certfile is copied into ssl's option certfile
https://github.com/processone/ejabberd/blob/e4d600729396a8539e48ac0cbd97ea1b210941cd/src/eldap.erl#L580
That option, among others, is provided as an argument when calling ssl:connect/4
https://github.com/processone/ejabberd/blob/e4d600729396a8539e48ac0cbd97ea1b210941cd/src/eldap.erl#L1140
So, the option that you set in ejabberd is named 'certfile' in ssl:connect, you can see here its documentation:
https://erlang.org/doc/man/ssl.html#connect-4
Searching for certfile in that page, it shows this description:
Path to a file containing the user certificate on PEM format.
Is it the public certificate of the LDAP server?
Try that one and comment here.
But then, what private key is expected?
Try not putting any private key. In any case, when the LDAP certificate was created, it produced a private key file, too.

How to generate TLS certificate bound gRPC server with protoc

Using protoc, in golang in my case, the generated server files are not bound to a TLS certificate and key that I have created. In fact I had to instantiate the grpc server using this approach:
creds, _ := credentials.NewServerTLSFromFile("server.crt", "server.key")
s := grpc.NewServer(grpc.Creds(creds))
s.Serve(listener)
and because this code is not the generated one, I need to use the above to register my service descriptor and handler:
s.RegisterService(&_My_serviceDesc, &handler.MailServer{})
The original generated _My_serviceDesc variable is in the generated package, therefore inaccessible from my main package, so I had to define it in mythemain package where I am starting the server above. Also, this same variable references a handler defined with an underscore _My_Handler which I also had to redefine in the main package.
I chacked the protoc documentation and help and there seems to be no way to do this otherwise. I wonder why it is not possible to associate it to the certificates that I need. This seems very odd...
TLS config is done on the gRPC server (when calling grpc.NewServer).
You can register service on the created server as normal.
See the TLS example here: https://github.com/grpc/grpc-go/tree/master/examples/features/encryption

Keycloak logging to JSON format message field

I have been trying to set up keycloak logging to be scraped by fluentd to be used in elasticsearch. So far I have used the provided CLI string to use in my helm values script.
cli:
# Custom CLI script
custom: |
/subsystem=logging/json-formatter=json:add(exception-output-type=formatted, pretty-print=true, meta-data={label=value})
/subsystem=logging/console-handler=CONSOLE:write-attribute(name=named-formatter, value=json)
However, as you can see in the picture provided, the logs that are generated seem to be completely json apart from the core of the log, the message field. Currently the message field is provided as comma separated key-value pairs. Is there any way to tell keycloak, jboss or wildfly that it needs to provide the message in JSON too? This allows me to efficiently search through the data in elastic.
Check this project on GitHub: keycloak_jsonlog_eventlistener: Outputs Keycloak events as JSON into the server log.
Keycloak JSON Log Eventlistener
Primarily written for the Jboss Keycloak docker image, it will output Keycloak events as JSON into the keycloak server log.
The idea is to parse logs once they get to logstash via journalbeat.
Tested with Keycloak version 8.0.1

PouchDB Replication throws error upon replication

When I try to replicate a remote couchdb (on ubuntu 14.04- 64 bit) with my local pouchdb, I encouter this strange error.
My couchdb is proxied via nginx and running on https. Traffic from client to nginx is ssl while nginx to couchdb is simple http. Cors requests are enabled in couchdb. Nginx configuration is most similar to couchdb recommended. Sync from database is working fine however getting below errors when debugging via chrome Version 54.0.2840.100 (64-bit) .
Following is the full stack trace of the error.
raven.min.js:2 Error: There was a problem getting docs.
at finishBatch (http://localhost:8100/lib/pouchdb/dist/pouchdb.js:6410:13)
at processQueue (http://localhost:8100/lib/ionic/js/ionic.bundle.js:27879:28)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:27895:27
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$digest (http://localhost:8100/lib/ionic/js/ionic.bundle.js:28969:31)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:29197:26
at completeOutstandingRequest (http://localhost:8100/lib/ionic/js/ionic.bundle.js:18706:10)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:18978:7
at d (http://localhost:8100/lib/raven-js/dist/raven.min.js:2:4308) undefineda.(anonymous function) # raven.min.js:2(anonymous function) # ionic.bundle.js:25642(anonymous function) # ionic.bundle.js:22421(anonymous function) # angular.min.js:2processQueue # ionic.bundle.js:27887(anonymous function) # ionic.bundle.js:27895$eval # ionic.bundle.js:29158$digest # ionic.bundle.js:28969(anonymous function) # ionic.bundle.js:29197completeOutstandingRequest # ionic.bundle.js:18706(anonymous function) # ionic.bundle.js:18978d # raven.min.js:2
raven.min.js:2 Paused in lessondb replicate Error: There was a problem getting docs.
at finishBatch (http://localhost:8100/lib/pouchdb/dist/pouchdb.js:6410:13)
at processQueue (http://localhost:8100/lib/ionic/js/ionic.bundle.js:27879:28)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:27895:27
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:29158:28)
at Scope.$digest (http://localhost:8100/lib/ionic/js/ionic.bundle.js:28969:31)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:29197:26
at completeOutstandingRequest (http://localhost:8100/lib/ionic/js/ionic.bundle.js:18706:10)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:18978:7
at d (http://localhost:8100/lib/raven-js/dist/raven.min.js:2:4308)
The network logs in chrome show that some requests are cancelled
I am using couchdb version - 1.6.1 and pouchdb version - 5.3.2.
I use following command to replicate dbs:
myDB.replicate.from(remote_db_url,{
live: true,
retry: true,
heartbeat: false
})
Also it would be great if someone can shed some light on heartbeat parameter .
Note: I'm not able to solve the error you describe. Maybe a full stack trace rather than a screenshot might help...
But I will try to shed some light on the heartbeat parameter: Reading the docs already helps a little. See the advanced options for the replicate method:
options.heartbeat: Configure the heartbeat supported by CouchDB which keeps the change connection alive.
So let's look into CouchDB's docs to see what this parameter does:
Networks are a tricky beast, and sometimes you don’t know whether there are no changes coming or your network connection went stale. If you add another query parameter, heartbeat=N, where N is a number, CouchDB will send you a newline character each N milliseconds. As long as you are receiving newline characters, you know there are no new change notifications, but CouchDB is still ready to send you the next one when it occurs.
So basically it seems to be a polling mechanism that sends a message (f.e. a newline) every n milliseconds (where n is the heartbeat value you specify) to make sure the connection between two databases is still working.
Setting the value to false will disable this mechanism.
Regarding the which value can be used for this parameter:
The PouchDB docs further state, that the changes method has a similar parameter described like this:
options.heartbeat: For http adapter only, time in milliseconds for server to give a heartbeat to keep long connections open. Defaults to 10000 (10 seconds), use false to disable the default.

WSO2 App Store throws error when attempting to save a users Application against mysql

API Store is throwing errors when I try to create or edit an application
java.sql.SQLException: Can't call commit when autocommit=true
I've added the setting of
init-command='set autocommit=0'
to the my.cnf file
I've also added the flag:
?relaxAutoCommit=true
to the connection string but to no avail. I continue to get this error.
I am using the same mysql database for both the WSO2_CARBON_DB and teh WSO2AM_DB plus I have a single publisher node and two separate store nodes all pointing to the same mysql datasource.
I notice the application edit is saved (or the new application is created) but the exception is still thrown in the console and an error message appears in the user interface (as per the error at the top of this question).
Is there some other setting, within the WSO2 conf files that I have to tweak in order to get this to work properly?
Add both autoReconnect and relaxAutoCommit flags to the jdbc url of your defined "WSO2AM_DB" datasource in master-datasources.xml file. This will resolve your issue.
<configuration>
<url>jdbc:mysql://localhost:3306/AM_DB?autoReconnect=true&relaxAutoCommit=true</url>
<username>xxxx</username>
<;password>xxxxx</password>
EDIT: I updated the url to reflect the correct syntax for escaping the ampersand.
just for the sake of completeness, the JDBC URL shoud be
jdbc:mysql://localhost:3306/WSO2CARBON_DB?autoReconnect=true&relaxAutoCommit=true