Authorization Credentials Stripped --- django, elastic beanstalk, oauth - django

I implemented a REST api in django with django-rest-framework and used oauth2 for authentication.
I tested with:
curl -X POST -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=password&username=YOUR_USERNAME&password=YOUR_PASSWORD" http://localhost:8000/oauth2/access_token/
and
curl -H "Authorization: Bearer <your-access-token>" http://localhost:8000/api/
on localhost with successful results consistent with the documentation.
When pushing this up to an existing AWS elastic beanstalk instance, I received:
{ "detail" : "Authentication credentials were not provided." }

I like the idea of just having some extra configuration on the standard place. In your .ebextensions directory create a wsgi_custom.config file with:
files:
"/etc/httpd/conf.d/wsgihacks.conf":
mode: "000644"
owner: root
group: root
content: |
WSGIPassAuthorization On
As posted here: https://forums.aws.amazon.com/message.jspa?messageID=376244

I thought the problem was with my configuration in django or some other error type instead of focusing on the differences between localhost and EB. The issue is with EB's Apache settings.
WSGIPassAuthorization is natively set to OFF, so it must be turned ON. This can be done in your *.config file in your .ebextensions folder with the following command added:
container_commands:
01_wsgipass:
command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'
Please let me know if I missed something or if there is a better way I should be looking at the problem. I could not find anything specifically about this anywhere on the web and thought this might save somebody hours of troubleshooting then feeling foolish.

I use a slightly different approach now. sahutchi's solution worked as long as env variables were not changed as Tom dickin pointed out. I dug a bit deeper inside EB and found out where the wsgi.conf template is located and added the "WSGIPassAuthorization On" option there.
commands:
WSGIPassAuthorization:
command: sed -i.bak '/WSGIScriptAlias/ a WSGIPassAuthorization On' config.py
cwd: /opt/elasticbeanstalk/hooks
That will always work, even when changing environment variables. I hope you find it useful.
Edit: Seems like lots of people are still hitting this response. I haven't used ElasticBeanstalk in a while, but I would look into using Manel Clos' solution below. I haven't tried it personally, but seems a much cleaner solution. This one is literally a hack on EBs scripts and could potentially break in the future if EB updates them, specially if they move them to a different location.

Though the above solution is interesting, there is another way. Keep the wsgi.conf VirtualHost configuration file you want to use in .ebextensions, and overwrite it in a post deploy hook (you can't do this pre-deploy because it will get re-generated (yes, I found this out the hard way). If you do this, to reboot, make sure to use the supervisorctl program to restart so as to get all your environment variables set properly. (I found this out the hard way as well.)
cp /tmp/wsgi.conf /etc/httpd/conf.d/wsgi.conf
/usr/local/bin/supervisorctl -c /opt/python/etc/supervisord.conf restart httpd
exit 0
01_python.config:
05_fixwsgiauth:
command: "cp .ebextensions/wsgi.conf /tmp"

Related

AWS Elastic Beanstalk - .ebextensions

My app currently uses a folder called "Documents" that is located in the root of the app. This is where it stores supporting docs, temporary files, uploaded files etc. I'm trying to move my app from Azure to Beanstalk and I don't know how to give permissions to this folder and sub-folders. I think it's supposed to be done using .ebextensions but I don't know how to format the config file. Can someone suggest how this config file should look? This is an ASP.NET app running on Windows/IIS.
Unfortunately, you cannot use .ebextensions to set permissions to files/folders within your deployment directory.
If you look at the event hooks for an elastic beanstalk deployment:
https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-windows-ec2.html#windows-container-commands
You'll find that commands run before the ec2 app and web server are set up, and
container_commands run after the ec2 app and web server are setup, but before your application version is deployed.
The solution is to use a wpp.targets file to set the necessary ACLs.
The following SO post is most useful
Can Web Deploy's setAcl provider be used on a sub-directory?
Given below is the sample .ebextensions config file to create a directory/file and modify the permissions and add some content to the file
====== .ebextensions/custom_directory.config ======
commands:
create_directory:
command: mkdir C:\inetpub\AspNetCoreWebApps\backgroundtasks\mydirectory
command: cacls C:\inetpub\AspNetCoreWebApps\backgroundtasks\mydirectory /t /e /g username:W
files:
"C:/inetpub/AspNetCoreWebApps/backgroundtasks/mydirectory/mytestfile.txt":
content: |
This is my Sample file created from ebextensions
ebextensions go into the root of the application source code through a directory called .ebextensions. For more information on how to use ebextensions, please go through the documentation here
Place a file 01_fix_permissions.config inside .ebextensions folder.
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/49_change_permissions.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
sudo chown -R ec2-user:ec2-user tmp/
Following that you can set your folder permissions as you want.
See this answer on Serverfault.
There are platform hooks that you can use to run scripts at various points during deployment that can get you around the shortcomings of the .ebextension Commands and Platform Commands that Napoli describes.
There seems to be some debate on whether or not this setup is officially supported, but judging by comments made on the AWS github, it seems to be not explicitly prohibited.
I can see where Napoli's answer could be the more standard MS way of doing things, but wpp.targets looks like hot trash IMO.
The general scheme of that answer is to use Commands/Platform commands to copy a script file into the appropriate platform hook directory (/opt/elasticbeanstalk/hooks or C:\Program Files\Amazon\ElasticBeanstalk\hooks\ ) to run at your desired stage of deployment.
I think its worth noting that differences exist between platforms and versions such as Amazon Linux 1 and Linux 2.
I hope this helps someone. It took me a day to gather that info and what's on this page and pick what I liked best.
Edit 11/4 - I would like to note that I saw some inconsistencies with the File .ebextension directive when trying to place scripts drirectly into the platform hook dir's during repeated deployments. Specifically the File directive failed to correctly move the backup copies named .bak/.bak1/etc. I would suggest using a Container Command to copy with overwriting from another directory into the desired hook directory to overcome this issue.

AWS ElasticBeanstalk: JWT token not being validated after configuration change

Using AWS console, I changed configuration setting of api key for a third-party service. Then all of a sudden, the following error is popping up on my live server.
{"detail":"Authentication credentials were not provided."}
It seems JWT token is not being validated(or passed). After hours of googling, I found that the error is caused by EB apache setting
Apparently, by setting,
container_commands:
01_wsgipass:
command: 'echo "WSGIPassAuthorization On" >> ../wsgi.conf'
in *.config, the problem should go away. I did exactly the same, with the code in wgsi_enabled_pass.config created within .ebextensions but it is still not working.
Please help the newbie pros! Thanks in advance!
Add this to a .ebextensions/customize_httpd.config file:
files:
"/etc/httpd/conf.d/wsgi_custom.conf":
mode: "000644"
owner: root
group: root
content: |
WSGIPassAuthorization On
This is more reliable then trying to concat to a conf file that may or may not exist.
#nbeuchat
If I rememeber correctly, try restarting the app from EBS console, or re-deploy the codes AFTER setting the container_commands in *.config as in the question. If this does not fix the problem, let me know. I'll look into what I did in the past to fix the bug.

(AWS) Security implications of adding an exclusion for user:wsgi in sudoers

While setting up a script to convert documents to PDF using libreoffice on AWS, I can't get libreoffice to --convert-to pdfwithout sudo as perhaps the user wsgi does not have write permissions to the /opt/python/current/app directory.
So I plan to solve this by appending the following line to the /etc/sudoers file:
wsgi ALL = NOPASSWD: /opt/libreoffice5.3/program/soffice.bin
As I want to automate this while deploying, in my .ebextensions/01_packages.config I have
container_commands:
01_edit_sudoers_only_once:
command: "echo 'wsgi ALL = NOPASSWD: /opt/libreoffice5.3/program/soffice.bin' >> /etc/sudoers"
test: "test ! -f .sudoers_edited"
02_mark_sudoers_as_edited:
command: "touch .sudoers_edited"
Is there a potential security issue with this?
There is a significant potential security issue with giving a web service process the ability to invoke things with sudo.
Giving it permission to write to directories containing code would also be unsafe.
You really need to identify what's being denied and why that matters. If error messages aren't sufficiently clear, you could use strace to observe the processes system calls and the resulting errors.

Add custom directives to wsgi.conf on AWS Beanstalk

I need to add ProxyPass directive to default wsgi.conf. I tried running sed command in container_commands script, but it seems to be called before wsgi.conf is created by deploy scripts. I found that i can drop custom hooks in /opt/elasticbeanstalk/hooks/appdeploy/post directory, but this method is not officially supported.
I wish I could find something more official, but it seems people are putting a wsgi.conf into their project, and using a container_commands script to move it to the appropriate location (which is not /etc/httpd/conf.d/wsgi.conf, though it does end up replacing /etc/httpd/conf.d/wsgi.conf in the end!):
container_commands:
04_wsgireplace:
command: "cp wsgi.conf ../wsgi.conf"
or
container_commands:
04_wsgireplace:
command: "cp .ebextensions/wsgi.conf ../wsgi.conf"
Depends on where in your project you've stored wsgi.conf, I assume. Looks like the script is being run from the app directory. I'm about to try it myself (for a flask project), and I'll report back!
There's a very related question here.
(References: 1,2,3)
Update: I tried it out (with wsgi.conf in .ebextensions), and it worked (for me).
I'm looking at another solution that builds on issue where default wsgi.conf needs to be extended. The concept comes from this blog post deploy
commands:
create_post_dir:
command: mkdir /opt/elasticbeanstalk/hooks/appdeploy/post
ignoreErrors: true
mv_post_appddeploy_script:
command: mv /tmp/99_wsgi_conf.sh /opt/elasticbeanstalk/hooks/appdeploy/post
files:
"/tmp/99_wsgi_conf.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
service httpd stop
echo "WSGIApplicationGroup %{GLOBAL}" >> /etc/httpd/conf.d/wsgi.conf
service httpd start
I think this is a more elegant solution - extend default rather than ignore. Can be made more sophisticated when required.

.ebextensions remove preinit script

Currently on deployment I get:
Hook /opt/elasticbeanstalk/hooks/preinit/30directories.sh failed
I want to remove the hook entirely using .ebextensions, I am currently using:
/.ebextensions/01-remove-unused.config
commands:
removeunused:
command: "rm -f /opt/elasticbeanstalk/hooks/preinit/30directories.sh"
ignoreErrors: true
files:
"/opt/elasticbeanstalk/hooks/preinit/30directories.sh":
mode: "000755"
owner: root
group: root
content: |
#!/usr/bin/env bash
ls
I'm not sure how relevant this is, but what platform of ElasticBeanstalk are you using? For 64bit Amazon Linux 2016.09 v2.3.0 running Docker 1.11.2 specifically (and maybe other platforms), I don't believe that there is any way to do this the way that you are describing.
Unfortunately, the preinit scripts are executed well before ElasticBeanstalk will inject .ebextensions into your environment, and they are only run when a fresh instance is started. To confirm this, you can inspect /var/log/eb-activity.log on a freshly deployed ElasticBeanstalk instance, which shows you everything related to the bootstrapping process that AWS logs for you. Search for Initialization/PreInitStage0/PreInitHook in this log file, and then also search for .ebextensions; you will see that the preinit scripts indeed get executed before most everything else, and .ebextensions files come much later. (for what it's worth, this blog post might help further help understand which hooks get run at which times)
What you could potentially do is configure an .ebextensions script to execute before all other non-preinit hooks scripts that will re-execute (and potentially undo changes from) all of the preinit scripts. However, I would guess that this would be more trouble than it is worth, as there are likely unintended side effects that could come from this.
At any rate, these are my findings trying to do something similar. Hopefully, this helps (despite the fact that I haven't technically solved your problem)!