Giter Site home page Giter Site logo

encrypted-session-nginx-module's Introduction

Name

encrypted-session-nginx-module - encrypt and decrypt nginx variable values

This module is not distributed with the Nginx source. See the installation instructions.

Table of Contents

Status

This module is production ready.

Synopsis

# key must be of 32 bytes long
encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";

# iv must not be longer than 16 bytes
#   default: "deadbeefdeadbeef" (w/o quotes)
encrypted_session_iv "1234567812345678";

# default: 1d (1 day)
encrypted_session_expires 3600; # in sec

location /encrypt {
    set $raw 'text to encrypted'; # from the ngx_rewrite module
    set_encrypt_session $session $raw;
    set_encode_base32 $session; # from the ngx_set_misc module

    add_header Set-Cookie 'my_login=$session';  # from the ngx_headers module

    # your content handler goes here...
}

location /decrypt {
    set_decode_base32 $session $cookie_my_login; # from the ngx_set_misc module
    set_decrypt_session $raw $session;

    if ($raw = '') {
        # bad session
    }

    # your content handler goes here...
}

Description

This module provides encryption and decryption support for nginx variables based on AES-256 with Mac.

This module is usually used with the ngx_set_misc module and the standard rewrite module's directives.

This module can be used to implement simple user login and ACL.

Usually, you just decrypt data in nginx level, and pass the unencrypted data to your FastCGI/HTTP backend, as in

location /blah {
    set_decrypt_session $raw_text $encrypted;

    # this directive is from the ngx_set_misc module
    set_escape_uri $escaped_raw_text $raw_text;

    fastcgi_param QUERY_STRING "uid=$uid";
    fastcgi_pass unix:/path/to/my/php/or/python/fastcgi.sock;
}

Lua web applications running directly on ngx_lua can call this module's directives directly from within Lua code:

local raw_text = ndk.set_var.set_decrypt_session(encrypted_text)

Back to TOC

Directives

Back to TOC

encrypted_session_key

syntax: encrypted_session_key <key>

default: no

context: http, server, server if, location, location if

Sets the key for the cipher (must be 32 bytes long). For example,

encrypted_session_key "abcdefghijklmnopqrstuvwxyz123456";

Back to TOC

encrypted_session_iv

syntax: encrypted_session_iv <iv>

default: encrypted_session_iv "deadbeefdeadbeef";

context: http, server, server if, location, location if

Sets the initial vector used for the cipher (must be no longer than 16 bytes).

For example,

encrypted_session_iv "12345678";

Back to TOC

encrypted_session_expires

syntax: encrypted_session_expires <time>

default: encrypted_session_expires 1d;

context: http, server, server if, location, location if

Sets expiration time difference (in seconds by default).

For example, consider the following configuration:

encypted_session_expires 1d;

When your session is being generated, ngx_encrypted_session will plant an expiration time (1 day in the future in this example) into the encrypted session string, such that when the session is being decrypted later, the server can pull the expiration time out of the session and compare it with the server's current system time. No matter how you transfer and store your session, like using cookies, or URI query arguments, or whatever.

People may confuse this setting with the expiration date of HTTP cookies. This directive simply controls when the session gets expired; it knows nothing about HTTP cookies. Even if the end user intercepted this session from cookie by himself and uses it later manually, the server will still reject it when the expiration time gets passed.

Back to TOC

set_encrypt_session

syntax: set_encrypt_session $target <value>

default: no

context: http, server, server if, location, location if

Encrypts the string value specified by the value argument and saves the result into the variable specified by $target.

For example,

set_encrypt_session $res $value;

will encrypts the value in the variable $value into the target variable $res.

The value argument can also be an nginx string value, for example,

set_encrypt_session $res "my value = $value";

The resulting data can later be decrypted via the set_decrypt_session directive.

Back to TOC

set_decrypt_session

syntax: set_decrypt_session $target <value>

default: no

context: http, server, server if, location, location if

Similar to set_encrypt_session, but performs the inverse operation, that is, to decrypt things.

Back to TOC

Installation

You're recommended to install this module (as well as the Nginx core and many other goodies) via the ngx_openresty bundle. See the detailed instructions for downloading and installing ngx_openresty into your system. This is the easiest and most safe way to set things up.

Alternatively, you can install this module manually with the Nginx source:

Grab the nginx source code from nginx.org, for example, the version 1.13.6 (see nginx compatibility), and then build the source with this module:

wget 'http://nginx.org/download/nginx-1.13.6.tar.gz'
tar -xzvf nginx-1.13.6.tar.gz
cd nginx-1.13.6/

Here we assume you would install you nginx under /opt/nginx/.
./configure --prefix=/opt/nginx \
    --with-http_ssl_module \
    --add-module=/path/to/encrypted-session-nginx-module

make -j2
make install

Download the latest version of the release tarball of this module from encrypted-session-nginx-module file list.

Also, this module is included and enabled by default in the ngx_openresty bundle.

OpenSSL should not be disabled in your Nginx build.

Back to TOC

Building as a dynamic module

Starting from NGINX 1.9.11, you can also compile this module as a dynamic module, by using the --add-dynamic-module=PATH option instead of --add-module=PATH on the ./configure command line above. And then you can explicitly load the module in your nginx.conf via the load_module directive, for example,

load_module /path/to/modules/ndk_http_module.so;  # assuming NDK is built as a dynamic module too
load_module /path/to/modules/ngx_http_encrypted_session_module.so;

Back to TOC

Compatibility

The following versions of Nginx should work with this module:

  • 1.13.x (last tested: 1.13.6)
  • 1.12.x
  • 1.11.x (last tested: 1.11.2)
  • 1.10.x
  • 1.9.x (last tested: 1.9.15)
  • 1.8.x
  • 1.7.x (last tested: 1.7.10)
  • 1.6.x
  • 1.5.x (last tested: 1.5.12)
  • 1.4.x (last tested: 1.4.4)
  • 1.2.x (last tested: 1.2.9)
  • 1.1.x (last tested: 1.1.5)
  • 1.0.x (last tested: 1.0.11)
  • 0.9.x (last tested: 0.9.4)
  • 0.8.x (last tested: 0.8.54)
  • 0.7.x >= 0.7.46 (last tested: 0.7.68)

Earlier versions of Nginx like 0.6.x and 0.5.x will not work.

If you find that any particular version of Nginx above 0.7.44 does not work with this module, please consider reporting a bug.

Back to TOC

Report Bugs

Although a lot of effort has been put into testing and code tuning, there must be some serious bugs lurking somewhere in this module. So whenever you are bitten by any quirks, please don't hesitate to

  1. send a bug report or even patches to [email protected],
  2. or create a ticket on the issue tracking interface provided by GitHub.

Back to TOC

Source Repository

Available on github at openresty/encrypted-session-nginx-module.

Back to TOC

Getting involved

You'll be very welcomed to submit patches to the author or just ask for a commit bit to the source repository on GitHub.

Back to TOC

Author

Yichun "agentzh" Zhang (章亦春) <[email protected]>

Back to TOC

Copyright & License

Copyright (c) 2009-2018, Yichun Zhang (agentzh) <[email protected]>, OpenResty Inc.

This module is licensed under the terms of the BSD license.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Back to TOC

See Also

Back to TOC

encrypted-session-nginx-module's People

Contributors

agentzh avatar bloodyknuckles avatar chipitsine avatar dyu avatar piotrsikora avatar spacewander avatar xiaocang avatar zhuizhuhaomeng avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

encrypted-session-nginx-module's Issues

undefined symbol: MD5

I have try to use this module as a dynamic module,but when i start nginx, occur an error:
dlopen() "/data/services/nginx-1.10.2/modules/ngx_http_encrypted_session_module.so" failed (/data/services/nginx-1.10.2/modules/ngx_http_encrypted_session_module.so: undefined symbol: MD5) in /data/services/nginx-1.10.2/conf/nginx.conf

operating system:Ubuntu 12.04 LTS 64bit
nginx version: nginx 1.10.2
encrypted-session-nginx-module version:0.06
gcc version: 4.6.3
configure command:
./configure --user=www-data --group=www-data --prefix=/data/services/nginx-1.10.2
--with-http_ssl_module
--with-http_realip_module
--with-http_addition_module
--with-http_sub_module
--with-http_dav_module
--with-http_flv_module
--with-http_mp4_module
--with-http_gzip_static_module
--with-http_random_index_module
--with-http_secure_link_module
--with-http_stub_status_module
--with-file-aio
--with-stream
--with-stream_ssl_module
--with-pcre=../pcre-8.39
--with-openssl=../openssl-1.0.2j
--with-zlib=../zlib-1.2.8
--add-dynamic-module=../nginx_module/ngx_devel_kit-0.3.0
--add-dynamic-module=../nginx_module/encrypted-session-nginx-module-0.06

nginx.conf:
load_module modules/ndk_http_module.so;
load_module modules/ngx_http_encrypted_session_module.so;

It seems that nginx can't find the function that is named MD5.

I try to use nm to list function,show below
nm libcrypto.a |grep MD5
0000000000000230 T MD5_Final
00000000000002e0 T MD5_Init
0000000000000220 T MD5_Transform
0000000000000000 T MD5_Update
0000000000000000 R MD5_version
0000000000000000 T MD5

nm nginx|grep MD5
000000000051e050 T MD5_Final
000000000051e100 T MD5_Init
000000000051e040 T MD5_Transform
000000000051de20 T MD5_Update
0000000000680960 R MD5_version

MD5 function is exists in libcrypto.a ,but it is not exists in nginx.

The module should support AES gcm mode.

At the moment the module does not support gcm mode. In order to keep backward compatibility, I suggest we introduce a directive which allows us to switch between cbc and gcm mode. By default, CBC should be enabled in order to keep backward compatibility.

encrypted_session_key $key; # introduced in PR https://github.com/openresty/encrypted-session-nginx-module/pull/24
encrypted_session_iv $iv; # introduced in PR https://github.com/openresty/encrypted-session-nginx-module/pull/24
encrypted_session_iv_in_content; # introduced in PR https://github.com/openresty/encrypted-session-nginx-module/pull/24
encrypted_session_mode gcm; # possible values are gcm or cbc.

Documentation is unclear, I request more examples

This module can be used to implement simple user login and ACL.

Can you provide full code (with php/python/perl) which uses your module with full power? I want to see very simple application like guestbook/todo-list, where will be login and ACL using this module. Sorry, but I currently can't figure out how to build login system using only/partially this module.

set_encrypt_session destroys proxied variables

I'm trying to encrypt a header that was returned from a proxy request., however, after executing set_encrypt_session, the $sent_http variable is blank. Here's a simple example

location = /api/login {
proxy_pass http://127.0.0.1:8080/login;

more_set_headers -s 200 "Token: $sent_http_auth_token";
set_encrypt_session $session $sent_http_auth_token;
set_encode_base32 $session; 
more_set_headers -s 200 "Token2: $session";
more_set_headers -s 200 "Token3: $sent_http_token";

}

Assuming that the proxy request returns a header called "Auth-Token" the following code will result with the "Token" header containing the contents of the "Auth-Token" header, "Token2" will contain an encrypted empty string, and "Token3" Will not be printed, as $sent_http_token is null.

I've tried all sorts of combinations, but I cannot get set_encrypt_session to work with anything expect a static text string. Even a string and a variable (like "TEST${sent_http_auth_token}") results in a null string

is there any nodejs equivalent implementation?

ngx_encrypted_session will plant an expiration time this part is hard. I don't know how to implement it in nodejs. I try to use this snippet to decrypt the string encrypted by encrypted-session-nginx-module, the output is a partial success:

>82^��/H�����j�EG��ɭ���tޡ�楠","permission":128,"username":"11111111","id":1}}c@9}

the nodejs decrypt snippet

import crypto from "crypto";

const ENC_KEY = "xxxxxxxx"; // set random encryption key
const IV = "xxxxxxx"; // set random initialisation vector
// ENC_KEY and IV can be generated as crypto.randomBytes(32).toString('hex');

// const phrase = "who let the dogs out";

const encrypt = (val: string) => {
  let cipher = crypto.createCipheriv("aes-256-cbc", ENC_KEY, IV);
  let encrypted = cipher.update(val, "utf8", "base64");
  encrypted += cipher.final("base64");
  return encrypted;
};

const decrypt = (encrypted: string) => {
  let decipher = crypto.createDecipheriv("aes-256-cbc", ENC_KEY, IV);
  let decrypted = decipher.update(encrypted, "base64", "utf8");
  return decrypted + decipher.final("utf8");
};

make error

objs/addon/src/ngx_http_encrypted_session_module.o:(.data+0x0): multiple definition of 'ngx_http_encrypted_session_module'
objs/addon/src/ngx_http_encrypted_session_module.o:(.data+0x0): first defined here
objs/addon/src/ngx_http_encrypted_session_cipher.o: In function 'ngx_http_encrypted_session_aes_mac_encrypt':
/opt/encrypted-session-nginx-module-0.08/src/ngx_http_encrypted_session_cipher.c:29: multiple definition of `ngx_http_encrypted_session_aes_mac_encrypt'
objs/addon/src/ngx_http_encrypted_session_cipher.o:/opt/encrypted-session-nginx-module-0.08/src/ngx_http_encrypted_session_cipher.c:29: first defined here
objs/addon/src/ngx_http_encrypted_session_cipher.o: In function 'ngx_http_encrypted_session_aes_mac_decrypt':
/opt/encrypted-session-nginx-module-0.08/src/ngx_http_encrypted_session_cipher.c:143: multiple definition of 'ngx_http_encrypted_session_aes_mac_decrypt'
objs/addon/src/ngx_http_encrypted_session_cipher.o:/opt/encrypted-session-nginx-module-0.08/src/ngx_http_encrypted_session_cipher.c:143: first defined here

openresty-1.13.6.2

Can we add more examples ?

one example use case may be doing nginx reverse proxying using WebSockets where the encrypted ips are passed in the header when the first response is sent from the server to the client and further the next following requests from the same client come with encrypted ip in the header, which nginx decodes and then routes the request to the correct downstream server with the ip same as we got after decrypting the (encrypted)ip from the header in the request (on load balancer or nginx).

  • In the above case we want to have the encryption logic on the server side and decryption logic on the load balancer (nginx) side.

Outdated module in new Linux distros

This module is totally outdated in any Linux distro that had removed OpenSSL 1 support (for example Debian 12). It is not recommended to use OpenSSL anymore as it is not secure anymore since previous year

When you try to compile the module it will show this error and it cannot be compiled:

encrypted-session-nginx-module/src/ngx_http_encrypted_session_cipher.c:90:5: error: ‘MD5’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
   90 |     MD5(data, data_size, p);
      |     ^~~
In file included from encrypted-session-nginx-module/src/ngx_http_encrypted_session_cipher.c:15:
/usr/include/openssl/md5.h:52:38: note: declared here
   52 | OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n,
      |                                      ^~~
encrypted-session-nginx-module/src/ngx_http_encrypted_session_cipher.c: In function ‘ngx_http_encrypted_session_aes_mac_decrypt’:
encrypted-session-nginx-module/src/ngx_http_encrypted_session_cipher.c:228:5: error: ‘MD5’ is deprecated: Since OpenSSL 3.0 [-Werror=deprecated-declarations]
  228 |     MD5(*dst, *dst_len, new_digest);
      |     ^~~
/usr/include/openssl/md5.h:52:38: note: declared here
   52 | OSSL_DEPRECATEDIN_3_0 unsigned char *MD5(const unsigned char *d, size_t n,
      |                                      ^~~

The 'encrypted_session_expires' directive in the example.

Hi,

Could you please change your example. Specifically, increase the value for the 'encrypted_session_expires' directive:

encrypted_session_expires 2; # in sec

For example to 30 seconds:
encrypted_session_expires 30; # in sec

We have a feedback from the real customer who had a problem using your example.
The value equal to 2 seconds is too short for testing by hand.

And I afraid we will get more such issues in the future.

Thank you.

Variables are not supported for configuring the module.

It would be extremely beneficial to support variables while configuring the module. This will give us the possibility to implement rotating IV for each encrypted session.

In addition, it allows us to mix the current module nicely with other extensions: e.g njs. Here is an example about the desired behaviour:

set $encryptionKey "abcdefghijklmnopqrstuvwxyz123456";
set $encryptionIV "1234567812345678";

encrypted_session_key $encryptionKey;
encrypted_session_iv $encryptionIV;

I would expect this to work but unfortunately the code treats this literally.

Encryption/Decryption Method

Hi There,

Assume I want to use this library and to decrypt and encrypt more things in PHP.
How can I achieve it?

What is the encryption method?
Do you have any PHP code example or can you please assist me in building one, using mcrypt or something.

Thanks

Question or Feature - Cache session in map ( instead of decrypt )

Great work!!
Is it possible to cache/store cookie id inside session map,
in order not to generate signature on every request but just looking up for cookie inside the map,

I am concerned about performance, because as i understand signatures generated on every request.

Use an HMAC, not a simple MD5 hash

The code, as-is, simply generates an MD5 hash of the data, which is trivially forgeable by an attacker.

Because the authenticity of the session cookie is not guaranteed, the CBC encryption used by this module is vulnerable to padding oracle attacks, which can trivially recover the plaintext of a session cookie.

You should:

  1. Use an HMAC construction, not a simple MD5 hash. OpenSSL provides this.
  2. Use a different key than the key used for encryption.
  3. Create an HMAC of the encrypted data, not of the plaintext.
  4. Use a constant-time comparison algorithm when validating the HMAC to avoid timing attacks.

(Or use an authenticated AES mode like GCM, but this will require OpenSSL 1.0.1+.)

For more details, please see Moxie's blog post on the 'doom principle'.

"set_decrypt_session" not working, got empty string. openresty bundle 1.15.8.1

good day,

when running demo encrypt/decrypt shown in project home, "set_decrypt_session" could not decrypt session, always got empty string.

location /encrypt {
    set $raw 'text to encrypted'; # from the ngx_rewrite module
    set_encrypt_session $session $raw;
    set_encode_base32 $session; # from the ngx_set_misc module

    add_header Set-Cookie 'my_login=$session';  # from the ngx_headers module

    # your content handler goes here...
}
location /decrypt {
    set_decode_base32 $session $cookie_my_login; # from the ngx_set_misc module
    set_decrypt_session **_$raw_** $session;

    if ($raw = '') {
        # bad session
    }

    # your content handler goes here...
}

the "$raw" is always empty string.

centos 7.4
openresty 1.15.8.1

thank you for the help.

Compiled filed with nginx-1.9.7

If i migrate ebuild to 1.9.7 end replace to new version encrypted-session-nginx-module
I recive error
Files found in blib/arch: installing files in blib/lib into architecture dependent library tree
/usr/bin/install: cannot stat '/var/tmp/portage/www-servers/nginx-1.9.7/work/encrypted-session-nginx-module-bc73c6721073a7a24606b22d5e21b2b366b58149/README': No such file or directory
!!! dodoc: /var/tmp/portage/www-servers/nginx-1.9.7/work/encrypted-session-nginx-module-bc73c6721073a7a24606b22d5e21b2b366b58149/README does not exist

Automatically renew session if there is activity?

For example if encrypted_session_expires is set at 1 hour, it seems appropriate to extend the expiry if the user is on the site continuously during that hour.

Seems like encrypted_session_expires is a site-wise property, and even if one manually change the cookie expiry, the backend logic of the module may not follow.
I am wondering what would be the best way to implement the above functionality using this module, if it is possible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.