Install psono.pw team based password manager on debian 10

So I needed a team based password manager and I stumbled upon this open source Django based project called PSONO .

Since their documentation has docker based installation I created my own guide on how to install both front-end and back-end along with nginx, LetsEncrypt free SSL on single Debian 10 instance .

Install and Configure postgrsql

1 . Install postgrsql from official repository

apt-get -y install curl gnupg2 ca-certificates lsb-release unzip
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'

wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -

apt-get update

apt-get -y install postgresql

sudo -iu postgres
createdb psono
psql psono

CREATE USER psono WITH PASSWORD 'dwYbayMa8NyN6IdeTQ9ZwqtEDitFhA4X';
GRANT ALL PRIVILEGES ON DATABASE "psono" to psono;
CREATE EXTENSION IF NOT EXISTS ltree;
CREATE EXTENSION IF NOT EXISTS "pgcrypto";
\q
exit
  1. edit /etc/postgresql/13/main/pg_hba.conf
# go to document bottom and alter these lines
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5

service postgresql restart
  1. Install psono.pw server requirements
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

useradd psono
sudo -iu psono
git clone https://gitlab.com/psono/psono-server.git ~/psono-server
exit
cd /home/psono/psono-server
pip3 install -r requirements.txt
sudo -iu psono
mkdir ~/.psono_server

4 . create and modify settings.yaml in /home/psono/.psono_server with following contents

# 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: ['domain.com']

# 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: 'the-mail-for-for-example-useraccount-activations@test.com'
EMAIL_HOST: 'smtp.example.com'
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: 10

# 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 your 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'

# Enables the management API, required for the psono-admin-client / admin portal
MANAGEMENT_ENABLED: True

# 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',
            ],
        },
    },
]
  1. Create database
python3  ~/psono-server/psono/manage.py migrate
python3 ./psono/manage.py createuser admin@domain.com password user@email.com
python3 ./psono/manage.py promoteuser admin@domain.com superuser
  1. Daemonize the server using supervisord
cat <<EOF > /etc/supervisor/conf.d/psono-server.conf
[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 
EOF 
supervisorctl reload 
supervisorctl start psono-server
  1. Setup cronjob
cat <<EOF > /etc/cron.d/psono_server
PATH=/usr/local/bin:/usr/bin:/bin
30 2 * * * psono python3 /home/psono/psono-server/psono/manage.py cleartoken >> /var/log/cron.log 2>&1
EOF

Install nginx and LetsEncrypt SSL

echo "deb http://nginx.org/packages/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
apt update
apt-get -y install nginx certbot python-certbot-nginx
  1. Configure nginx vhost, SSL and depoly client webapp along with admin webapp
cat <<EOF > /etc/nginx/conf.d/psono.conf
server {
listen 80;
server_name vault.domain.com;
add_header Referrer-Policy same-origin;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
client_max_body_size 256m;

gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon;

root /var/www/html;

location ~/server(.*)$ {
proxy_set_header        Host \$host;
proxy_set_header        X-Real-IP \$remote_addr;
proxy_set_header        X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto \$scheme;

add_header Last-Modified \$date_gmt;
add_header Pragma "no-cache";
add_header Cache-Control "private, max-age=0, no-cache, no-store";
if_modified_since off;
expires off;
etag off;

proxy_pass          http://localhost:10100\$1;
}
}
EOF

service nginx restart
certbot --nginx

mkdir -p /var/www/html
cd /var/www/html
wget https://psono.jfrog.io/psono/psono/client/latest/webclient.zip
unzip webclient.zip
mkdir portal
cd portal
wget https://psono.jfrog.io/psono/psono/admin-client/latest/webclient.zip
unzip webclient.zip
  1. edit /var/www/html/config.json and /var/www/html/portal/config.json
{
  "backend_servers": [{
    "title": "domain.com",
    "url": "https://vault.domain.com/server",
    "domain": "alkafeel.info"
  }],
  "base_url": "https://vault.domain.com/",
  "allow_custom_server": false,
  "allow_registration": false,
  "allow_lost_password": false,
  "disable_download_bar": false,
  "authentication_methods": ["AUTHKEY", "LDAP"],
  "saml_provider": []
}

Reference

https://doc.psono.com/admin/installation/install-preparation.html

Comments

Popular posts from this blog

Upgrade an Arabic vbulletin 3.x to 5.x and convert it's mysql data from cp1256/latin1 to utf8

CEPH Bluestore WAL/DB on Software RAID1 for redundancy