0

I am running an api behind flask in python and connections are handled through nginx and uwsgi.

Some of the api routes use pycrypto but am getting errors when using nginx on port 80 regarding this line in the pycrypto source.

The full traceback is:

Traceback (most recent call last):
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1817, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask_cors/extension.py", line 188, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "./application.py", line 113, in new_user
    decrypted_json = crypt.decrypt_json(encrypted)
  File "./crypto_module/crypt.py", line 201, in decrypt_json
    decrypted_text = cryptor.decrypt(data_to_decrypt, PASSWORD)
  File "./crypto_module/crypt.py", line 112, in decrypt
    encryption_key = self._pbkdf2(password, encryption_salt, iterations=iterations)
  File "./crypto_module/crypt.py", line 184, in _pbkdf2
    return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations, prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/Crypto/Protocol/KDF.py", line 110, in PBKDF2
    password = tobytes(password)
  File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/Crypto/Util/py3compat.py", line 85, in tobytes
    return ''.join(s)
TypeError

The TypeError is never specifically mentioned for some reason. The error also does not show when running the server with the basic python application.py command on the default port 5000. When letting nginx and uwsgi handle the connections, I get the Internal Server Error shown above. Not really sure what's happening. All other non-crypto routes go through fine.

Update: running the server one level up in uwsgi with the following command will also work. Nginx still does not:

uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi 

Update 2: Now getting another TypeError that's a little more descriptive but I still think the data being sent in the request is not being handled the same way/correctly with nginx as it is with uwsgi or flask.

...
  File "./crypto_module/crypt.py", line 202, in <lambda>
    return KDF.PBKDF2(password, salt, dkLen=key_length, count=iterations, prf=lambda p, s: hmac.new(p, s, hashlib.sha256).digest())
  File "/usr/lib/python2.7/hmac.py", line 133, in new
    return HMAC(key, msg, digestmod)
  File "/usr/lib/python2.7/hmac.py", line 68, in __init__
    if len(key) > blocksize:
TypeError: object of type 'NoneType' has no len()

I should also note that crypt.py is RNCryptor-python

internetwhy
  • 635
  • 1
  • 6
  • 19
  • What is the output with the TypeError? If it isn't printing automatically catch the exception and print it. `join` expects everything in that list to be a string. Looks like there is something wrong with the password you are sending. Why it would be happening with nginx and not other things maybe depends on your nginx conf. Can you post that as well as where you are getting PASSWORD from? – user3591723 Feb 01 '16 at 02:35
  • `PASSWORD` is coming from an environment variable. That code was on line 201 which keeps getting included in the trace, even if nothing of importance to the trace happens. This time it just grabbed a comment. Also tried to do a try/except on the code but the error appeared on the `try:` line this time. `File "/home/ubuntu/test/testvenv/local/lib/python2.7/site-packages/Crypto/Util/py3compat.py", line 85, in tobytes try: TypeError` – internetwhy Feb 01 '16 at 02:59
  • Can you post your nginx conf and how you're running uwsgi? The problem is probably in either the `PASSWORD` or `encrypted` variables. There really should be something following that `TypeError`, like this `TypeError: sequence item N: expected string, FOOTYPE found` for instance – user3591723 Feb 01 '16 at 08:09
  • [Here are my settings](http://pastebin.com/DhrASkj9). The only thing I really changed was with nginx by adding some buffer, timeout, and gzip settings in `nginx.conf`. The error still happens with the settings disabled. The same `PASSWORD` and `encrypted` will work if run with the flask server as I mentioned before, which makes me think it has to be either a Nginx or Uwsgi issue. Thanks for continuing to help! – internetwhy Feb 01 '16 at 14:56
  • update: running the server one level up in uwsgi with the command `uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi` works. Nginx still does not. – internetwhy Feb 01 '16 at 15:59
  • update: new TypeError with context this time: http://pastebin.com/v7Si5vxb – internetwhy Feb 01 '16 at 20:14
  • For debugging this try to switch the simplest nginx/uwsgi conf you can. Try [this nginx](http://pastebin.com/c58kATBK) and [this uwsgi](http://pastebin.com/yAsGmMWF). Note that I've opened permissions to everyone with that uwsgi. You can play with all of that later, we just want to get the app actually running correctly first. – user3591723 Feb 02 '16 at 02:37
  • Thank you. I had tried the error both ways with my original conf files and the barebones but both had the same error. Turns out it was the unix protocol line in the nginx site file and the amount of forward slashes. Thank you for your help, @user3591723! – internetwhy Feb 02 '16 at 02:53
  • Ha! I actually was going to mention the possibility of needing two extra /'s, but I pulled that conf file from an old project that is actually working. Strange. Maybe it is an nginx version issue or something – user3591723 Feb 02 '16 at 07:52

1 Answers1

0

Got it working.

In /etc/nginx/sites-enabled/test

uwsgi_pass unix:/...;

Should be

uwsgi_pass unix:///...;

The original error also stemmed from the password used in the crypto file. The password was retrieved from the system's environment variables. I later found out that Nginx doesn't come with any functionality to natively use environment variables but a workaround is explained here.

internetwhy
  • 635
  • 1
  • 6
  • 19