Psono Free Password Management Software
Open Source Credentials Manager for Teams and Enterprises
Psono is an open source password manager designed for teams. It can be self-hosted at the client side and has multilayered encryption for maximum security.
Overview
Psono is a free password manager for teams. Most open source password managers that are free to use do not offer the option to scale and host password managers across your team or on your servers, respectively. However, with Psono you get a free to use, completely secure, open source credentials manager that is designed keeping in mind teams.
With Psono, you can deploy the password manager on your own server and allow up to 10 users to store their important information and access it as well. As an open source password manager, it also has multiple device and cross platform compatibility such as iOS, Android, MacOS, Linux and browsers like Chrome, Edge, Safari and more.
The main convenience of using open source password managers like Psono is the ability to access your critical information from anywhere, at any time and the ability to store other information like credit card data, banking information and more. Psono is convenient and efficient, especially for teams that are logging into and accessing different applications or servers that are sensitive.
Psono is a self-hosted password manager. It can be used as a web extension, deployed on your server, accessed through the web client application or installed through the Docker. You can also access it on your mobile phones or simply install it into your CI CD pipeline for any project.
System Requirements
While installing Psono for Ubuntu make sure you have the following system requirements:
- Ubuntu 20.04
- Server access through static IP or a domain/host name pointing to it.
- Make sure server has 2GB RAM and 2 cores
- A non-root user with sudo permissions
Features
Here are some good to know features about Psono:
- Psono uses a multilayered encryption where three layers of encryption protect the data when it is being transferred from a browser to the Psono application server. The server encrypts the data using Salso20 stream cipher along with the Poly1305 MAC code that reduces the necessity of relying on the DBA (data base administrator) for validation.
- You can use the Password Generator to produce a password consisting of a minimum of 6 characters or more consisting of symbols, numbers, lower case/upper case characters etc.
- With Psono you can easily autofill your login credentials for different websites after providing the necessary details on the application.
- Passwords can also be accessed when you are offline through the client side applications.
- You can also create emergency codes to access passwords in case of a digital legacy problem such as the passing away of a team member or unavailability in case of an emergency.
- Psono also detects any password breach that may have happened and reports on it in time.
- You will find multiple API keys that allow for the integration of password during builds or startup scripts.
Installation
This guide will install the Psono server, and runs it with gunicorn and nginx. It has been tested on Ubuntu 18.04.
- Become root
sudo su
- Install some generic stuff
apt-get update
apt-get install -y \
git \
libyaml-dev \
libpython3-dev \
libpq-dev \
libffi-dev \
python3-dev \
python-pip \
python3-pip \
python3-psycopg2 \
postgresql-client \
haveged \
libsasl2-dev \
libldap2-dev \
libssl-dev \
supervisor
pip3 install gunicorn
- Create psono user
adduser psono
- Become the psono user
su psono
- Clone git repository
git clone https://gitlab.com/psono/psono-server.git ~/psono-server
- Install python requirements
Ctrl + D
cd /home/psono/psono-server
pip3 install -r requirements.txt
su psono
- Create settings folder
mkdir ~/.psono_server
- Create a settings.yaml in ~/.psono_server/ with the following content
# generate the following six parameters with the following command
# python3 ~/psono-server/psono/manage.py generateserverkeys
SECRET_KEY: 'SOME SUPER SECRET KEY THAT SHOULD BE RANDOM AND 32 OR MORE DIGITS LONG'
ACTIVATION_LINK_SECRET: 'SOME SUPER SECRET ACTIVATION LINK SECRET THAT SHOULD BE RANDOM AND 32 OR MORE DIGITS LONG'
DB_SECRET: 'SOME SUPER SECRET DB SECRET THAT SHOULD BE RANDOM AND 32 OR MORE DIGITS LONG'
EMAIL_SECRET_SALT: '$2b$12$XUG.sKxC2jmkUvWQjg53.e'
PRIVATE_KEY: '302650c3c82f7111c2e8ceb660d32173cdc8c3d7717f1d4f982aad5234648fcb'
PUBLIC_KEY: '02da2ad857321d701d754a7e60d0a147cdbc400ff4465e1f57bc2d9fbfeddf0b'
# The URL of the web client (path to e.g activate.html without the trailing slash)
# WEB_CLIENT_URL: 'https://www.psono.pw'
# Switch DEBUG to false if you go into production
DEBUG: False
# Adjust this according to Django Documentation https://docs.djangoproject.com/en/2.2/ref/settings/
ALLOWED_HOSTS: ['*']
# Should be your domain without "www.". Will be the last part of the username
ALLOWED_DOMAINS: ['psono.pw']
# If you want to disable registration, you can comment in the following line
# ALLOW_REGISTRATION: False
# If you want to disable the lost password functionality, you can comment in the following line
# ALLOW_LOST_PASSWORD: False
# If you want to enforce that the email address and username needs to match upon registration
# ENFORCE_MATCHING_USERNAME_AND_EMAIL: False
# If you want to restrict registration to some email addresses you can specify here a list of domains to filter
# REGISTRATION_EMAIL_FILTER: ['company1.com', 'company2.com']
# Should be the URL of the host under which the host is reachable
# If you open the url and append /info/ to it you should have a text similar to {"info":"{\"version\": \"....}
HOST_URL: 'https://www.psono.pw/server'
# The email used to send emails, e.g. for activation
# ATTENTION: If executed in a docker container, then "localhost" will resolve to the docker container, so
# "localhost" will not work as host. Use the public IP or DNS record of the server.
EMAIL_FROM: <span id="cloak820118571330d66e81d06c4c2b562de4">This email address is being protected from spambots. You need JavaScript enabled to view it.</span><script type="text/javascript">document.getElementById('cloak820118571330d66e81d06c4c2b562de4').innerHTML='';var prefix='ma'+'il'+'to';var path='hr'+'ef'+'=';var addy820118571330d66e81d06c4c2b562de4=''the-mail-for-for-example-useraccount-activations'+'@';addy820118571330d66e81d06c4c2b562de4=addy820118571330d66e81d06c4c2b562de4+'test'+'.'+'com';var addy_text820118571330d66e81d06c4c2b562de4=''the-mail-for-for-example-useraccount-activations'+'@'+'test'+'.'+'com';document.getElementById('cloak820118571330d66e81d06c4c2b562de4').innerHTML+='<a '+path+'\''+prefix+':'+addy820118571330d66e81d06c4c2b562de4+'\'>'+addy_text820118571330d66e81d06c4c2b562de4+'<\/a>';</script>'
EMAIL_HOST: 'localhost'
EMAIL_HOST_USER: ''
EMAIL_HOST_PASSWORD : ''
EMAIL_PORT: 25
EMAIL_SUBJECT_PREFIX: ''
EMAIL_USE_TLS: False
EMAIL_USE_SSL: False
EMAIL_SSL_CERTFILE:
EMAIL_SSL_KEYFILE:
EMAIL_TIMEOUT:
# In case one wants to use mailgun, comment in below lines and provide the mailgun access key and server name
# EMAIL_BACKEND: 'anymail.backends.mailgun.EmailBackend'
# MAILGUN_ACCESS_KEY: ''
# MAILGUN_SERVER_NAME: ''
# In case you want to offer Yubikey support, create a pair of credentials here https://upgrade.yubico.com/getapikey/
# and update the following two lines before commenting them in
# YUBIKEY_CLIENT_ID: '123456'
# YUBIKEY_SECRET_KEY: '8I65IA6ASDFIUHGIH5021FKJA='
# If you have own Yubico servers, you can specify here the urls as a list
# YUBICO_API_URLS: ['https://api.yubico.com/wsapi/2.0/verify']
# Cache enabled without belows Redis may lead to unexpected behaviour
# Cache with Redis
# By default you should use something different than database 0 or 1, e.g. 13 (default max is 16, can be configured in
# redis.conf) possible URLS are:
# redis://[:password]@localhost:6379/0
# rediss://[:password]@localhost:6379/0
# unix://[:password]@/path/to/socket.sock?db=0
# CACHE_ENABLE: False
# CACHE_REDIS: False
# CACHE_REDIS_LOCATION: 'redis://127.0.0.1:6379/13'
# Disables Throttling (necessary for unittests to pass) by overriding the cache with a dummy cache
# https://docs.djangoproject.com/en/2.2/topics/cache/#dummy-caching-for-development
# THROTTLING: False
# Enables the management API, required for the psono-admin-client / admin portal
# MANAGEMENT_ENABLED: False
# Enables the fileserver API, required for the psono-fileserver
# FILESERVER_HANDLER_ENABLED: False
# Enables files for the client
# FILES_ENABLED: False
# Allows that users can search for partial usernames
# ALLOW_USER_SEARCH_BY_USERNAME_PARTIAL: True
# Allows that users can search for email addresses too
# ALLOW_USER_SEARCH_BY_EMAIL: True
# Disables central security reports
# DISABLE_CENTRAL_SECURITY_REPORTS: True
# Configures a system wide DUO connection for all clients
# DUO_INTEGRATION_KEY: ''
# DUO_SECRET_KEY: ''
# DUO_API_HOSTNAME: ''
# If you are using the DUO proxy, you can configure here the necessary HTTP proxy
# DUO_PROXY_HOST: 'the-ip-or-dns-name-goes-here'
# DUO_PROXY_PORT: 80
# DUO_PROXY_TYPE: 'CONNECT'
# If your proxy requires specific headers you can also configure these here
# DUO_PROXY_HEADERS: ''
# Normally only one of the configured second factors needs to be solved. Setting this to True forces the client to solve all
# MULTIFACTOR_ENABLED: True
# Allows admins to limit the offered second factors in the client
# ALLOWED_SECOND_FACTORS: ['yubikey_otp', 'google_authenticator', 'duo']
# Your Postgres Database credentials
# ATTENTION: If executed in a docker container, then "localhost" will resolve to the docker container, so
# "localhost" will not work as host. Use the public IP or DNS record of the server.
DATABASES:
default:
'ENGINE': 'django.db.backends.postgresql_psycopg2'
'NAME': 'psono'
'USER': 'psono'
'PASSWORD': 'password'
'HOST': 'localhost'
'PORT': '5432'
# for master / slave replication setup comment in the following (all reads will be redirected to the slave
# slave:
# 'ENGINE': 'django.db.backends.postgresql_psycopg2'
# 'NAME': 'YourPostgresDatabase'
# 'USER': 'YourPostgresUser'
# 'PASSWORD': 'YourPostgresPassword'
# 'HOST': 'YourPostgresHost'
# 'PORT': 'YourPostgresPort'
# Update the path to your templates folder
# If you do not want to change it (yet) you can leave it like it is.
TEMPLATES: [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': ['/home/psono/psono-server/psono/templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Update database credentials / secrets / paths like described in the comments above.
To send a test e-mail to something@something.com execute:
python3 ~/psono-server/psono/manage.py sendtestmail something@something.com
- If you receive this test e-mail, e-mail should be configured proper.
- Create our database
python3 ~/psono-server/psono/manage.py migrate
- Run the psono server
cd ~/psono-server/psono
gunicorn --bind 0.0.0.0:10100 wsgi
- This will start the Psono server on port 10100. If you open now http://your-ip:10100/info/ should see something like this:
{"info":"{\"version\": \"....}
- Become root again
Ctrl + D
- Create supervisor config. Create a psono-server.conf in /etc/supervisor/conf.d/ with the following content:
[program:psono-server]
command = /usr/local/bin/gunicorn --bind 127.0.0.1:10100 wsgi
directory=/home/psono/psono-server/psono
user = psono
autostart=true
autorestart=true
redirect_stderr=true
- You may have realised that we changed the bind. This way Psono is only accessible from localhost, which is fine as we will proxy requests with nginx.
- Reload supervisorctl
supervisorctl reload
- Setup cleanup job
crontab -e
- and add the following line:
30 2 * * * psono python3 /home/psono/psono-server/psono/manage.py cleartoken >> /var/log/cron.log 2>&1
- To run the Psono password manager in production, a reverse proxy is needed, to handle the ssl offloading and glue the psono server and webclient together. Follow the guide to setup reverse proxy as a next step.