# Install Server CE
Installation instruction for the Community Edition of the Psono server
# Preamble
At this point we assume that you already have a postgres database running, ready for connections. If not follow this guide to setup postgres.
# Installation with Docker
Generate keys
Execute the command below to generate your cryptographic keys which you need in the next step.
docker run --rm -ti psono/psono-combo:latest python3 ./psono/manage.py generateserverkeys
Create a settings.yaml
Create a settings.yaml in e.g.
/opt/docker/psono/
with the following content. Replace the keys at the top with the keys that you just generated.# Replace the keys below with the one from the generateserverkeys command. 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: '02...0b' PUBLIC_KEY: '02...0b' # The URL of the web client (path to e.g activate.html without the trailing slash) # WEB_CLIENT_URL: 'https://psono.example.com' # 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: ['example.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://psono.example.com/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 (Default is set to False) # 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', 'webauthn'] # 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' # The path to the template folder can be "shadowed" if required later TEMPLATES: [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['/root/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
Test E-Mail
The most tedious step is usually for me to get e-mail working. To make this step easier, we offer a small test script which will send a test e-mail.
To send a test e-mail to
something@something.com
execute:docker run --rm \ -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \ -ti psono/psono-server:latest python3 ./psono/manage.py sendtestmail something@something.com
If you receive this test e-mail, it should be configured properly.
Prepare the database
docker run --rm \ -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \ -ti psono/psono-server:latest python3 ./psono/manage.py migrate
Run the Psono server container and expose the server port
docker run --name psono-server \ --sysctl net.core.somaxconn=65535 \ -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml \ -d --restart=unless-stopped -p 10100:80 psono/psono-server:latest
This will start the Psono server on port 10100. If you open now http://your-ip:10100/info/ you should see something like this:
{"info":"{\"version\": \"....}
If you don't, please make sure no firewall is blocking your request.
Setup cleanup job
Execute the following command:
crontab -e
and add the following line:
30 2 * * * docker run --rm -v /opt/docker/psono/settings.yaml:/root/.psono_server/settings.yaml -ti psono/psono-server:latest python3 ./psono/manage.py cleartoken >> /var/log/cron.log 2>&1
Setup Reverse Proxy
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.
# Installation for Ubuntu
This guide will install the Psono server, and runs it with gunicorn and nginx. It has been tested on Ubuntu 18.04.
WARNING
This installation type is meant for developers and auditors. For production purposes we recommend the docker installation.
Become root
sudo -i
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 # become root again cd /home/psono/psono-server pip3 install -r requirements.txt su psono # become psono again
Create settings folder
mkdir ~/.psono_server
Generate keys
Execute the command below to generate your cryptographic keys which you need in the next step.
python3 ~/psono-server/psono/manage.py generateserverkeys
Create a settings.yaml
Create a settings.yaml in e.g.
~/.psono_server/
with the following content. Replace the keys at the top with the keys that you just generated.# Replace the keys below with the one from the generateserverkeys command. SECRET_KEY: 'Ndhz7mBYUVDEG9hNeYVgPcE4a4MRJiLQADQ5DNOUV2l7OmyAFtQ6hR6GyIErr7xF' ACTIVATION_LINK_SECRET: 'TT3dXwD6lysyqthlpQUl8WlGPeG6WSVdQBd0JBOS9ZwNynuuPsHfPJ7ComLVQsyE' DB_SECRET: 'TXUXjPOvsWYGnBNnKrITd1tvWvKOmk1sN8FMJopDuCtPT1y2pbP56R9pWIEHjAJV' EMAIL_SECRET_SALT: '$2b$12$o9HKh8yvEqYe6k0Do/YZdu' PRIVATE_KEY: 'debe5115baf449b0c53ac112d5df314bb7adcb46308b6847908c97b06746a65c' PUBLIC_KEY: '9b8f35c6261fa9840f00b86026fe11ec4e0e0cbf84b2f860713da1e442c79577' # The URL of the web client (path to e.g activate.html without the trailing slash) # WEB_CLIENT_URL: 'https://psono.example.com' # 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: ['example.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://psono.example.com/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: 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', 'webauthn'] # 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
Test E-Mail
The most tedious step is usually for me to get e-mail working. To make this step easier, we offer a small test script which will send a test e-mail.
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, it should be configured properly.
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\": \"....}
If you don't, please make sure no firewall is blocking your request.
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
Now you can control the Psono server with supervisorctrl commands e.g.
- supervisorctl status psono-server
- supervisorctl start psono-server
- supervisorctl stop psono-server
Setup cleanup job
Execute the following command:
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
Setup Reverse Proxy
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.
# Installation for CentOS
This guide will install the Psono server, and runs it with gunicorn and nginx. It has been tested on CentOS 7.
WARNING
This installation type is meant for developers and auditors. For production purposes we recommend the docker installation.
Become root
sudo -i
Install some generic stuff
yum -y update yum -y install https://repo.ius.io/ius-release-el7.rpm https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm yum -y update yum -y install \ git \ gcc \ curl \ openssl-devel \ bzip2-devel \ libffi-devel \ postgresql \ postgresql-devel \ haveged \ openldap-devel \ make \ supervisor curl -O https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz tar -xzf Python-3.8.1.tgz cd Python-3.8.1/ ./configure --enable-optimizations make altinstall ln -s /usr/local/bin/python3.8 /usr/bin/python3 ln -s /usr/local/bin/pip3.8 /usr/bin/pip3 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 # become root again cd /home/psono/psono-server pip3 install -r requirements.txt su psono # become psono again
Create settings folder
mkdir ~/.psono_server
Generate keys
Execute the command below to generate your cryptographic keys which you need in the next step.
python3 ~/psono-server/psono/manage.py generateserverkeys
Create a settings.yaml
Create a settings.yaml in e.g.
~/.psono_server/
with the following content. Replace the keys at the top with the keys that you just generated.# Replace the keys below with the one from the generateserverkeys command. SECRET_KEY: 'Ndhz7mBYUVDEG9hNeYVgPcE4a4MRJiLQADQ5DNOUV2l7OmyAFtQ6hR6GyIErr7xF' ACTIVATION_LINK_SECRET: 'TT3dXwD6lysyqthlpQUl8WlGPeG6WSVdQBd0JBOS9ZwNynuuPsHfPJ7ComLVQsyE' DB_SECRET: 'TXUXjPOvsWYGnBNnKrITd1tvWvKOmk1sN8FMJopDuCtPT1y2pbP56R9pWIEHjAJV' EMAIL_SECRET_SALT: '$2b$12$o9HKh8yvEqYe6k0Do/YZdu' PRIVATE_KEY: 'debe5115baf449b0c53ac112d5df314bb7adcb46308b6847908c97b06746a65c' PUBLIC_KEY: '9b8f35c6261fa9840f00b86026fe11ec4e0e0cbf84b2f860713da1e442c79577' # The URL of the web client (path to e.g activate.html without the trailing slash) # WEB_CLIENT_URL: 'https://psono.example.com' # 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: ['example.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://psono.example.com/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: 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', 'webauthn'] # 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
Test E-Mail
The most tedious step is usually for me to get e-mail working.
To make this step easier, we offer a small test script which will
send a test e-mail.
To send a test e-mail to `something@something.com` execute:
```bash
python3 ~/psono-server/psono/manage.py sendtestmail something@something.com
```
If you receive this test e-mail, it should be configured properly.
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/ you should see something like this:
{"info":"{\"version\": \"....}
If you don't, please make sure no firewall is blocking your request.
Become root again
Ctrl + D
Create supervisor config
Create a psono-server.ini in /etc/supervisord.d/ with the following content:
[program:psono-server] command = /usr/bin/gunicorn --bind 0.0.0.0: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.
Start supervisord and register autostart
systemctl enable --now supervisord
Now you can control the Psono server with supervisorctrl commands e.g.
- supervisorctl status psono-server
- supervisorctl start psono-server
- supervisorctl stop psono-server
Setup cleanup job
Execute the following command:
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
Setup Reverse Proxy
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.
# Note: Installation behind Firewall
If you have put your installation behind a firewall, you have to whitelist some ports / adjust some settings, that all features work:
- Incoming TCP connections (usually Port 443) from clients to servers
- Incoming TCP connections (usually Port 443) from fileservers to servers
- Incoming TCP connections (usually Port 80) from clients to servers (will do the redirect to https)
- Outgoing TCP 5432 to database server
- Outgoing TCP / UDP 123 connection to time.google.com: Psono requires a synced time for various reasons (Google Authenticator, YubiKey, Throttling, Replay protection, ...) Therefore it has a healthcheck, to compare the local time to a time server (by default time.google.com). You can specify your own timeserver in the settings.yaml with the "TIME_SERVER" parameter. If you are confident that your server always has the correct time you can also disable the healthcheck with "HEALTHCHECK_TIME_SYNC_ENABLED: False".
- Outgoing TCP 443 connection to api*.yubico.com: Psono validates YubiKey OTP tokens against the official Yubikey Servers. You can use your own YubiKey server with the "YUBICO_API_URLS" parameter in the settings.yaml
- Outgoing TCP 443 connection to api*.duosecurity.com: Psono initiates connection to the Duo api server, whenever someone uses Duo's 2 Factor authentication. Psono also supports Duo's auth proxy duo.com/docs/authproxy-reference (opens new window) by configuring DUO_PROXY_HOST, DUO_PROXY_PORT and DUO_PROXY_TYPE
- Outgoing TCP connection (usually 25, 465, 587 or 2525) to your email server