Can deploy Psono.pw self hosted on Ubuntu 20.04 LTS Server.
- Ubuntu 20.04 LTS
- Docker
- Nginx Systemd
version: '3'
services:
psono_db:
image: postgres:10.4
container_name: psono_db
environment:
- POSTGRES_USER=psono
- POSTGRES_PASSWORD=psono
- POSTGRES_DB=psono
- DB_EXTENSION=pgcrypto
- DB_EXTENSION=ltree
volumes:
- "psonodb:/var/lib/postgresql/data"
networks:
- backend
ports:
- "5432:5432"
restart: always
psono_backend:
image: psono/psono-server:latest
container_name: psono_backend
volumes:
- "${PWD}/settings.yaml:/root/.psono_server/settings.yaml"
links:
- psono_db
networks:
- backend
ports:
- "10100:80"
restart: always
depends_on:
- psono_db
# psono_reverse:
# image: nginx:latest
# container_name: psono_reverse
# volumes:
# - "${PWD}/vhost.conf:/etc/nginx/conf.d/vhost.conf"
# - "${PWD}/ssl:/etc/ssl"
# networks:
# - backend
# - outside
# ports:
# - "443:443"
# restart: always
# depends_on:
# - psono_db
# - psono_backend
psono_client:
image: psono/psono-client:latest
container_name: psono_client
networks:
- backend
ports:
- "10101:80"
restart: always
depends_on:
- psono_db
- psono_backend
psono_admin:
image: psono/psono-admin-client:latest
container_name: psono_admin
networks:
- backend
ports:
- "10102:80"
restart: always
depends_on:
- psono_db
- psono_backend
volumes:
psonodb:
# external: true
networks:
outside:
external: true
backend:
# generate the following six parameters with the following command
# python3 ~/psono-server/psono/manage.py generateserverkeys
SECRET_KEY: '+?`\\x&.rFq4sd~R,ZB/vPN~jn~19hif?~L#TuRgMg.L=(wSmtq'
ACTIVATION_LINK_SECRET: '6`MmEO=QG,qBZ;,(i\\_b*L"U[EXUWoFEZGUW&={bYM6.rJeaSZ'
DB_SECRET: '\\"z.%%WkV5DQF`j~xvYfVM7M;?{lV_SzD=iURd{C?yL4N_Zolk'
EMAIL_SECRET_SALT: '$2b$12$JwSQyeRva7lf0lg6PYBeaO'
PRIVATE_KEY: '40661064be34a7926ba098950d3c5a98bd1e6613d907a1cd6d6b6235ef472089'
PUBLIC_KEY: 'f56a7369392a12fd88eef4387b81857a3680af3bc11488b5e17ac30b50664014'
# 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/1.10/ref/settings/
ALLOWED_HOSTS: ['*']
# Should be your domain without "www.". Will be the last part of the username
ALLOWED_DOMAINS: ['dev-psono.com']
# If you want to disable registration, you can comment in the following line
# ALLOW_REGISTRATION: 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 you should have a text similar to {"detail":"Authentication credentials were not provided."}
HOST_URL: 'https://dev-psono.com/server'
# The email used to send emails, e.g. for activation
EMAIL_FROM: 'REDACTED'
EMAIL_HOST: 'REDACTED'
EMAIL_HOST_USER: 'REDACTED'
EMAIL_HOST_PASSWORD : 'REDACTED'
EMAIL_PORT: 587
EMAIL_SUBJECT_PREFIX: 'Psono'
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: 'django_mailgun.MailgunBackend'
# 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/1.11/topics/cache/#dummy-caching-for-development
# THROTTLING: False
# Enables the management API, required for the psono-admin-client / admin portal
MANAGEMENT_ENABLED: True
# 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
# Only necessary if the psono-client runs on a sub path (no trailing slash) e.g. "https://wwww.psono.pw"
# WEB_CLIENT_URL: ''
# Prevents the use of the last X passwords. 0 disables it.
# DISABLE_LAST_PASSWORDS: 0
# Your Postgres Database credentials
DATABASES:
default:
'ENGINE': 'django.db.backends.postgresql_psycopg2'
'NAME': 'psono'
'USER': 'psono'
'PASSWORD': 'psono'
'HOST': 'psono_db'
'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': ['/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',
],
},
},
]
[program:psono-server]
command = /usr/bin/gunicorn --bind 127.0.0.1:10100 psono.wsgi
directory=/home/psono/psono-server/psono
user = psono
autostart=true
autorestart=true
redirect_stderr=true
- change
10.0.2.115:10101
to your IP Address
server {
listen 80;
server_name dev-psono.com;
return 301 https://$host$request_uri;
}
server {
listen 80;
server_name www.dev-psono.com;
return 301 https://$host$request_uri;
}
#server {
# listen 443 ssl http2;
# server_name dev-psono.com;
# return 301 https://www.$host$request_uri;
#
# ssl_protocols TLSv1.2;
# ssl_prefer_server_ciphers on;
# ssl_session_cache shared:SSL:10m;
# ssl_session_tickets off;
# ssl_stapling on;
# ssl_stapling_verify on;
# ssl_session_timeout 1d;
# resolver 8.8.8.8 8.8.4.4 valid=300s;
# resolver_timeout 5s;
# ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
#
## add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
##
## 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";
#
# # If you have the admin webclient installed too behind this reverse proxy domaain, then you have to change the following from:
# # "connect-src 'self' https://api.pwnedpasswords.com;" to "connect-src 'self' https://dev-psono.com https://static.psono.com https://api.pwnedpasswords.com;"
## add_header Content-Security-Policy "default-src 'none'; connect-src 'self' https://api.pwnedpasswords.com; font-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'self'";
#
# ssl_certificate /etc/letsencrypt/live/psono/server.crt;
# ssl_certificate_key /etc/letsencrypt/live/psono/server.key;
#}
server {
listen 443 ssl http2;
server_name www.dev-psono.com;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_timeout 1d;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
# Comment this in if you know what you are doing
# add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
# 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";
# If you have the admin webclient installed too behind this reverse proxy domaain, then you have to change the following from:
# "connect-src 'self' https://api.pwnedpasswords.com;" to "connect-src 'self' https://dev-psono.com https://static.psono.com https://api.pwnedpasswords.com;"
# add_header Content-Security-Policy "default-src 'none'; connect-src 'self' https://api.pwnedpasswords.com; font-src 'self'; img-src 'self' data:; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'self'";
ssl_certificate /etc/letsencrypt/live/psono/server.crt;
ssl_certificate_key /etc/letsencrypt/live/psono/server.key;
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 {
rewrite ^/server/(.*) /$1 break;
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://10.0.2.115:10100;
}
location ~* ^/portal.*\.(?:ico|css|js|gif|jpe?g|png)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
#Comment in the following lines if you have the admin webclient running in a docker container
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;
proxy_pass http://10.0.2.115:10102;
proxy_redirect http://10.0.2.115:10102 https://dev-psono.com;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
#Comment in the following lines if you have the webclient running in a docker container
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;
proxy_pass http://10.0.2.115:10101;
proxy_redirect http://10.0.2.115:10101 https://dev-psono.com;
}
# Comment in the following lines if you have the admin webclient running in a docker container
location /portal {
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;
proxy_read_timeout 90;
proxy_pass http://10.0.2.115:10102;
proxy_redirect http://10.0.2.115:10102 https://dev-psono.com;
}
# Comment in the following lines if you have the webclient running in a docker container
location / {
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;
proxy_pass http://10.0.2.115:10101;
proxy_read_timeout 90;
proxy_redirect http://10.0.2.115:10101 https://dev-psono.com;
}
}
docker exec -it psono_backend ash
python3 ~/psono/manage.py createuser admin@dev-psono.com PASSWORD admin@dev-psono.com
python3 ~/psono/manage.py promoteuser admin@dev-psono.com superuser