Very simple way of password protecting django app on OpenShift - python

Is there a very simple way of creating password access using .htaccess whilst testing. I don't want to do anything that would interfere with the application. Is there a way of doing this within OpenShift?

You can use password protection with .htaccess and .htapasswd to avoid public access on your site while it's not yet launched.
In your .htaccess add these:
AuthUserFile /absolute/path/to/your/.htpasswd
AuthType Basic
AuthName "Just testing"
Require valid-user
Then you need the password file. You can create it with this unix command:
htpasswd -c /absolute/path/to/your/.htpasswd testusername
You will be asked for the password for this user and the .htpasswd file will be created for you with the credentials. The password is stored hashed.
Without -c you can add further users to existing files:
htpasswd /absolute/path/to/your/.htpasswd nextusername
For access you can submit auth data within url. Most browser support that, some gives you a warning about phishing:
http://testusername:password123#www.example.com/

Related

Connecting remotely to a MongoDB database without storing password in plaintext

I am trying to remotely connect to a MongoDB database but don't want to store the password for the database in plaintext in the code. What's a good method for encrypting/decrypting the password so it's not available to anyone with the source code? The source code will be on GitHub.
I'm working with Python and PyMongo for connecting to the database. The database has authentication enabled in the mongod.conf file. The database is hosted on a Ubunutu 18.04 instance running in AWS.
It would also be nice to have the IP address of the server encrypted also as i've had security issues before with people accessing the database due to the code being available on GitHub and then presumably scraped by bots.
My current URI looks like this
URI = "mongo serverip --username mongo --authenticationDatabase admin -p"
I would like the IP address and password to be encrypted in some way so that the password and IP aren't publicly available in the source code.
There is only and and simple way:
If you don't want the password and the server name to be included in your public repository don't write it into a file that is pushed into that repository.
One way to do so would be to create a config file for secret data and add it to the .gitignore file. At run-time open the config file, read the secret data from it and use it in your script.
Another way would be to provide the secret data (password an server name) as command line parameters to your script.
Any other way that "encrypts" (obfuscates) the password is insecure as long as the repository contains also the obvious or hidden key. This can be decoded with a little effort.
All the options provided by Robert makes complete sense. However, I would like to give one more:
You can store username and password under your environment variables under .bash_profile and access the corresponding env var in python.
Example: -
In .bash_profile:
export USRNM='myname'
export PASS='password'
In python:
import os
username = os.environ.get('USRNM')
password = os.environ.get('PASS')
This way, username and password will not be present in your project directory and cant be accessed by looking at the source code.
PS: Further encryption can be added to the password string stored in .bash_profile.

How could I obtain GSSAPI credentials without having krb5.keytab on user machine?

I'm getting the following error when trying to obtain GSSAPI credentials on my machine:
server_creds = gssapi.Credentials(usage='init', name=server_name)
GSSError: Major (851968): Unspecified GSS failure. Minor code may provide more information, Minor (2): Key table file '/etc/krb5.keytab' not found
Here is what I have already found in Kerberos keytab introduction:
A keytab is a file containing pairs of Kerberos principals and encrypted keys (these are derived from the Kerberos password). You can use this file to log into Kerberos without being prompted for a password. The most common personal use of keytab files is to allow scripts to authenticate to Kerberos without human interaction, or store a password in a plaintext file.
Well, it's completely acceptable for me even if my program will actually require human interaction in order to authenticate. Is there any way to use Kerberos client on end-user system without /etc/krb5.keytab file, even if it means asking password on each authentication?
It makes no sense to "even if it means asking password on each authentication". This defeats the purpose of Kerberos.
You can do the following:
Your user does "kinit" in the shell or similar via a login manager
You have a binding for gss_acquire_cred_with_password() for Python
Evaluate both

Simplest way to switch the linux user for the web-server (django) without sudo?

Aim: to create user friendly web interface to linux program without any ssh (console) terrible stuff.
I have chosen Python + Django + Apache.
Problem: user should login through the browser to linux user and then all user`s requests should be served on behalf of this linux user.
By now, server is run as root and when user login through a browser, server root can switch to required user using django user name:
uid = pwd.getpwnam(userName)[2]
os.setuid(uid)
and it can execute all django stuff on behalf of appropriate user.
The problem is that server must be run as root!
How could I provide possibility to normally run server with usual apache user rights with providing login to linux user through a browser? (Just get user Name and PWD from the Http POST request and login to appropriate user using Python)?
Update: I need to map any user via web to specific linux user to give him his home directory to execute specific linux program only as this specific user! I guess something like this is realized in webmin?
Possible solution: I could execute su userName but it doesn't work without terminal:
p = subprocess.Popen(["su", "test"], stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.STDOUT)
suOUT = p.communicate(input="test")[0]
print suOUT
I just got:
su: must be run from a terminal
I'm not sure what "standard" approaches are for dealing with this problem. However, this is a simple technique for environments with a small number of users that doesn't involve sudo, nor changing UID inside the web server (this is likely to be very problematic for concurrent access by multiple users).
Launch a daemon process for each user having access to this application. This process should itself serve web requests for that user over FastCGI (substitute for protocol of your choice). Your web server should have some user to port number mapping. Then, redirect your gateway's requests to the proper FastCGI process based on the logon used by the Django user.
Example (using internal redirects by NGINX, assuming setup with FastCGI):
User foo logs on to Django web application
User requests page /.../
Django application receives request for /.../ by user foo
Django application returns custom HTTP header X-Accel-Redirect to indicate internal redirect to /delegate/foo/.../.
NGINX forwards finds location /delegate/foo/ associated to a FastCGI handler on port 9000
FastCGI handler is running as user foo and grants access to stuff in home directory.
You can substitute the web server and communication protocol to combinations of your choice. I used FastCGI here because it allows to write both the gateway and the handler as Django applications. I chose NGINX because of the internal redirect feature. This prevents impersonation by direct use of /delegate/foo/.../ URLs by users other than foo.
Update
Example:
Assuming you have the flup module, you can start a FastCGI server directly using Django. To start a Django application over FastCGI under a specific user account, you can use:
sudo -u $user python /absolute/path/to/manage.py runfcgi host=127.0.0.1 port=$port
Substitute the $user for the user name and $port for a unique port for that user (no two users can share the same port).
Assuming an NGINX configuration, you can set this up like:
location /user/$user {
internal;
fastcgi_pass 127.0.0.1:$port;
# additional FastCGI configuration...
}
Make sure to add one such directive for each $user and $port combination above.
Then, from your front-end Django application, you can check permissions and stuff using:
#login_required
def central_dispatch_view ( request ):
response = HttpResponse()
response['X-Accel-Redirect'] = '/user/'+request.user.username
return response
Disclaimer: This is totally untested, and almost a year after the original answer, I'm not sure this is possible, mainly because the documentation on XSendFile in NGINX specifies that this should work with static files. I haven't inquired any further to know if you can actually perform an internal NGINX redirect from a FastCGI application.
Alternate solution:
A better approach might not involve internal redirects, but instead to use a FastCGI authorizer. Basically, a FastCGI is a program that your webserver runs before serving a request. Then, you can bypass the shady internal redirect thing and just have a FastCGI authorizer that check if the request accessing /user/foo/ actually can from a Django user logged in as foo. This authorizer program won't be able to run as a Django application (since this is not an HTTP request/response cycle), but you can write it using flup and access your Django settings.
You can include the wsgi user in the sudoers file, and limit the commands and arguments it can run. Why can't you use sudo?
for example:
Cmnd_Alias TRUSTED_CMDS = /bin/su johndoe /some/command, \
/bin/su janedoe /some/command
my_wsgi_user ALL = NOPASSWD: TRUSTED_CMDS
From the security perspective, you should assume the users have shell access - I think its ok for a coorporate intranet but not for a public site.
From python/django you will be able to call ['sudo', '/bin/su', 'johndoe', '/some/command'].
Another solution if you really can't use sudo (with NOPASSWD) is connect via ssh using the user credentials (user, password) with paramiko.

Database password requested when running "manage.py test"

When I try to run
manage.py test
a database password prompt shows.
Previously, tests would run without me having to enter the db password manaually.
I just updated my database to postgres 8.4. I assume it's some setting I'm forgetting.
How can I configure it to run tests without asking for the password?
Additional Info:
I created the database with the user 'postgres', but am accessing in django with the user, 'postgis'. I checked the permissions of these users, and they are the same.
When running the test the db and tables get created fine (no password requested).
It's only when it installs 'Custom SQL' that the password is requested.
RESOLUTION
As Carl pointed out the ~/.pgpass file [*nix] and %APPDATA%\postgresql\pgpass.conf (where %APPDATA% refers to the Application Data subdirectory in the user's profile) [windows] allows you to configure databases so you don't need to enter a password each time.
See the postgres documentation: The Password File
I checked my configuration and it looks like this file was/is auto-created. I updated my password file and now django tests run without the need to manually enter a password on each custom sql installation.
Django tests use a different database; your DATABASE_NAME setting with "_test" appended. My first guess would be that somewhere in your Postgres authentication config (either in pg_hba.conf or in a ~/.pgpass file), you are allowing access to DATABASE_NAME with no password, but you don't have the same config for DATABASE_NAME_test.
I assume it's some setting I'm
forgetting.
Not trying to make a fool out of you, but sometimes simple solutions are overlooked:
Did you set the DATABASE_PASSWORD setting in your settings.py file?

Trac Using Database Authentication

Is it possible to use a database for authentication with Trac?
.htpasswd auth is not desired in this install.
Using Trac .11 and MySQL as the database. Trac is currently using the database, but provides no authentication.
Out of the box, Trac doesn't actually do its own authentication, it leaves it up to the web server. So, you've got a wealth of Apache-related options available to you. You could maybe look at something like auth_mysql to let you keep user credentials in a database.
Alternatively, take a look at the AccountManagerPlugin on trac-hacks.org
You can use Account Manager Plugin with SessionStore
The AccountManagerPlugin offers several features for managing user accounts:
allow users to register new accounts
login via an HTML form instead of using HTTP authentication
allow existing users to change their passwords or delete their accounts
send a new password to users who’ve forgotten their password
administration of user accounts
Please refer to http://trac-hacks.org/wiki/AccountManagerPlugin
Do the following on your trac.ini
[components]
; be sure to enable the component
acct_mgr.svnserve.* = enabled
acct_mgr.svnserve.svnservepasswordstore = enabled
; choose one of the hash methods
acct_mgr.pwhash.htdigesthashmethod = enabled
acct_mgr.pwhash.htpasswdhashmethod = enabled
[account-manager]
password_store = SvnServePasswordStore
password_file = /path/to/svn/repos/conf/passwd
; choose one of the hash methods
hash_method = HtDigestHashMethod
hash_method = HtPasswdHashMethod
Now trac will use user in the database

Categories

Resources