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

MF-651 - X509 Mutual TLS authentication #676

Merged
merged 21 commits into from
Apr 2, 2019
Merged

Conversation

dborovcanin
Copy link
Collaborator

What does this do?

This pull request introduces a new authorization method using x.509 certificates.

Which issue(s) does this PR fix/relate to?

This pull request resolves #651.

List any changes that modify/break current functionality

In order to establish a connection and send a message, Thing needs to provide a valid client certificate. The default configuration is unchanged and by default, running Docker composition does not include mutual authentication.

Have you included tests for your changes?

I have tested all the features manually. However, there are no automated tests provided.

Did you document any new/modified functionality?

Yes, I have.

@codecov-io
Copy link

codecov-io commented Mar 28, 2019

Codecov Report

Merging #676 into master will increase coverage by 0.05%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #676      +/-   ##
==========================================
+ Coverage   86.29%   86.35%   +0.05%     
==========================================
  Files          62       62              
  Lines        3722     3722              
==========================================
+ Hits         3212     3214       +2     
+ Misses        353      352       -1     
+ Partials      157      156       -1
Impacted Files Coverage Δ
writers/cassandra/init.go 80% <0%> (+20%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bc49f6a...e539f2c. Read the comment docs.

@dborovcanin dborovcanin force-pushed the MF-651 branch 2 times, most recently from 86f04a8 to 4cc8ac7 Compare March 28, 2019 16:14
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;

#
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure that I like removing useful info

@@ -201,29 +147,6 @@ http {
}
}

# Proxy pass to mainflux-mqtt-adapter
location /mqtt {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you removing MQTT-over-WS support?

@@ -242,23 +165,17 @@ http {
}
}

# MQTT
Copy link
Contributor

Choose a reason for hiding this comment

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

Why removing this?


ca:
openssl req -newkey rsa:2048 -x509 -nodes -sha512 -days 1095 \
-keyout $(CRT_LOCATION)/ca.key -out $(CRT_LOCATION)/ca.crt -subj "/CN=localhost/O=Mainflux/OU=IoT/emailAddress=info@mainflux.com"
Copy link
Contributor

Choose a reason for hiding this comment

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

Please use global vars here if you defined them.

Copy link
Contributor

Choose a reason for hiding this comment

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

All of this should not go into Makefile IMHO.

Rather make a spearate script that can be used independently of Makefile, than call it from Makefile with appropriate parameter.

Makefiles are not very readable and can be easily polluted.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't like this Makefile, either. However, I find it extremely simple to use it as a wrapper around OpenSSL. It's easier and more convenient than a simple shell script. Do you have any suggestion? We can completely remove it and describe openssl commands in docs, but for the user, it's easier to use make something than to run complex openssl commands.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK to keep it.


function access(s) {
s.on('upload', function (data) {
while (data == '') {
Copy link
Contributor

Choose a reason for hiding this comment

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

All of this should happen only if the cert has been verified/valid.

Since we use ssl_verify_client on;, NginX will put a validity flag in a certain internal var, and this must be checked.

Copy link
Contributor

Choose a reason for hiding this comment

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

I still do not see where you check this var for MQTT. This should be probably checked somewhere in the script (at least it is like this in Lua).

docker/ssl/access.js Outdated Show resolved Hide resolved
return '';
}

function setKey(r) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Add info that this is for HTTP and WS only.

mkdocs.yml Outdated Show resolved Hide resolved
docker/ssl/access.js Outdated Show resolved Hide resolved
docker/docker-compose.yml Show resolved Hide resolved
docker/nginx/nginx-key.conf Outdated Show resolved Hide resolved
| PROTOCOL NAME |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
| VERSION | FLAGS | KEEP ALIVE |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
Copy link
Contributor

Choose a reason for hiding this comment

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

PLease align

docker/ssl/authorization.js Outdated Show resolved Hide resolved
This method extracts Password field.
*/

var packet_type_flags_byte = data.codePointAt(0);
Copy link
Contributor

@drasko drasko Mar 29, 2019

Choose a reason for hiding this comment

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

Looks like you started parsing packet flags fields without even checking if the message type is CONNECT. If it is not CONNECT, we should exit right after this check of a first byte.

@dborovcanin dborovcanin force-pushed the MF-651 branch 4 times, most recently from 2e8865b to 4a966e9 Compare March 29, 2019 20:07
@dborovcanin dborovcanin marked this pull request as ready for review March 29, 2019 20:08
@dborovcanin dborovcanin requested a review from drasko March 29, 2019 20:08
@@ -0,0 +1,256 @@
##
Copy link
Contributor

Choose a reason for hiding this comment

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

No need for double ##. One is enough.


ca:
openssl req -newkey rsa:2048 -x509 -nodes -sha512 -days 1095 \
-keyout $(CRT_LOCATION)/ca.key -out $(CRT_LOCATION)/ca.crt -subj "/CN=localhost/O=Mainflux/OU=IoT/emailAddress=info@mainflux.com"
Copy link
Contributor

Choose a reason for hiding this comment

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

OK to keep it.


s.on('upload', function (data) {
while (data == '') {
return s.AGAIN
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we really need this s.AGAIN - nginx/njs#111 (comment)

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe is a good idea to disable TLS 1.0 and 1.1, there are few well-known vulnerabilities, it's not secure and even newer versions of browsers removed support. TLS 1.3 is preferred but we can keep TLS 1.2 also (a lot of peoples still use it).

# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same question for TLS 1.0 1.1

# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same for TLS version

include /etc/nginx/mime.types;
default_type application/octet-stream;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
Copy link
Collaborator

Choose a reason for hiding this comment

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

TLS version

docker/nginx/nginx-x509.conf Show resolved Hide resolved
add_header Access-Control-Allow-Methods '*';
add_header Access-Control-Allow-Headers '*';

server_name localhost;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe also think to put this as ENV var so I can use custom domain easy.

client.csr Outdated
@@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE REQUEST-----
Copy link
Collaborator

Choose a reason for hiding this comment

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

Where this file is located? client.csr looks like it's in the project root?

client.key Outdated
@@ -0,0 +1,51 @@
-----BEGIN RSA PRIVATE KEY-----
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same question for location of the file.

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
docker/nginx/nginx-x509.conf Show resolved Hide resolved
Copy link
Contributor

@drasko drasko left a comment

Choose a reason for hiding this comment

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

LGTM

@drasko drasko merged commit f9b17d5 into absmach:master Apr 2, 2019
@drasko
Copy link
Contributor

drasko commented Apr 2, 2019

Merged! Great work @dusanb94, very important feature!

davide83 pushed a commit to davide83/mainflux that referenced this pull request May 13, 2019
* Use NginX njs module for mutual authentication

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add Makefile for cert management

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move certificates make context to scripts dir

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move nginx.conf to separate directory

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Choose between two NginX configurations

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move certs Makefile to docker/ssl/

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Use default key-based authentication

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add mTLS docs

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Update Makefile

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add check if Authorization is present

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add check if Will Flag is 1

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Return MQTT over WS

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Fix docker-compose.yml volume mapping

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Rename security section in docs

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add message type check before message parsing

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove double comments

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove s.AGAIN in return

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Update Makefile

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove CSR and key from the root

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Drop TLS version below 1.2

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add comments for cert and key paths

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
@dborovcanin dborovcanin deleted the MF-651 branch September 30, 2019 12:44
manuio pushed a commit that referenced this pull request Oct 12, 2020
* Use NginX njs module for mutual authentication

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add Makefile for cert management

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move certificates make context to scripts dir

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move nginx.conf to separate directory

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Choose between two NginX configurations

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Move certs Makefile to docker/ssl/

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Use default key-based authentication

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add mTLS docs

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Update Makefile

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add check if Authorization is present

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add check if Will Flag is 1

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Return MQTT over WS

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Fix docker-compose.yml volume mapping

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Rename security section in docs

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add message type check before message parsing

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove double comments

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove s.AGAIN in return

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Update Makefile

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Remove CSR and key from the root

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Drop TLS version below 1.2

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>

* Add comments for cert and key paths

Signed-off-by: Dušan Borovčanin <dusan.borovcanin@mainflux.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

X509 Mutual TLS authentication
4 participants