This documentation provides a guide for installing ADF in a testing or small-scale environment without high availability and fault tolerance. Transitioning to a high availability setup requires additional planning and complexity in setup. However, the testing version allows users to become familiar with the software and can potentially be upgraded to a high availability/fault-tolerant installation in the future.
Before proceeding with the installation, ensure you have the following prerequisites:
Swarm mode enables you to set up virtual networks and utilize different compose file features. This allows for proper service isolation while exposing only necessary ones.
For Docker Swarm setup, please address following instruction: Docker setup
You may use boilerplate files prepared for test deployment, but they may need some changes, so we would look in more details at file contents below.
Download following archive for quickstart:
adf_quickstart.zip
/opt/adf
├── adf.env
├── adf-xxx.yml
├── backup
│ └── db
├── cert
├── conf
│ ├── access.yaml
│ ├── cert.pem
│ ├── config.yaml
│ └── key.pem
├── db
├── log
├── radius
│ ├── var_cache_samba
│ ├── var_lib_samba
│ └── var_lib_samba_private
├── _start.sh
├── _stop.sh
└── tgbot_template_vpn.hbs
Create folder tree with following commands:
mkdir -p /opt/adf
cd /opt/adf
mkdir -p backup/db cert conf db db/_dump log
mkdir -p radius/var_cache_samba radius/var_lib_samba radius/var_lib_samba_private radius/_tmp
Configuration of ADF consists of multiple options, all of them has default values, but these default values were not intended to be 100% compatible with new installations, as every installation differs, at least by adresses, domain names etc.
You would need to define bare minimum of configuration options to make things up and running.
Configuration files should be in yaml format.
Create following structure on the VM:
/opt/adf/config/
.env <- shared options
access.yaml <- accounts for getting configuration by adfconfcli
config.yaml <- combined options for all services
key.pem <- TLS key in PEM format
cert.pem <- TLS certificate in PEM format
(self-signed or issued by your CA)
Let’s start making configuration, where main 2nd factor would be Telegram messenger. Change options according to your setup
#MULTIPLE_SERVICES
TIMEZONE=Europe/Belgrade
HOST=0.0.0.0
SERVE_TLS=1
DB_URL=mongodb://mongo:27017
AUDIT_DB_NAME=adf_audit
USERS_DB_NAME=adf
TGOTP_DB_NAME=tgotp
SYSLOGADDR=log:24224
# tgbot+adf_admin
TG_BOT_NAME=my_telegram_bot
# ADF_ADMIN
JWT_SECRET=apha6iedoh0meev2Shagie6xi7ohn7oequichaifahtieNg4vah5peuwohhei8di
CERT_PATH=config/cert.pem
KEY_PATH=config/key.pem
MAILER_HOST=mail.my-mail-domain.tld
MAILER_USER=adf@my-mail-domain.tld
MAILER_PASS=**my-mail-server-password**
# Optional mailer restrictions (messages would be only sent there):
MAILER_RESTRICTIONS="^[^@]+@my-mail-domain.tld\$"
#TGOTPBOT
# following options are tgbot API creds for admin/auth/radius
TGBOT_USER=bot
TGBOT_PASS=bot
TG_API_KEY=123456789:my-telegram-bot-secret-api-key
# log
DB_SHARDED=1
LOGLEVEL=info
SYSLOGPROTO=udp
SYSLOGADDR=log:24224
# If we need to forward copy of logs to remote server
#REMOTE_SYSLOG_HOST=10.0.0.2
#REMOTE_SYSLOG_PORT=1999
#REMOTE_SYSLOG_PROTO=tcp
#radius
RADIUS_SECRET=some-radius-secret
TGBOT_URI=https://tgotpbot:8643
AUTH_API_URI=https://adfadmin:3443
RADIUS_SERVER=radius:1817
LOGFORMAT=json
# only if you intend to use selfservice:
SELFSERVICE_SECRET: "64 byte random secret"
Within configuration file you may invoke shared options from .env file by using either one of formats:
OPTION: "{SHARED_OPTION_NAME}"
or
OPTION: ${SHARED_OPTION_NAME}
both formats are valid.
Let’s build our configuration:
adfadmin:
SECRET:
JWT_SECRET: "{JWT_SECRET}"
MAILER_PASS: "{MAILER_PASS}"
TGBOT_USER: ${TGBOT_USER}
TGBOT_PASS: ${TGBOT_PASS}
# only if you intend to use selfservice:
# SELFSERVICE_SECRET: ${SELFSERVICE_SECRET}
VAR:
TZ: ${TIMEZONE}
MONGO_URI: "{DB_URL}"
# host - host for HTTPs server to listen. Default: 0.0.0.0
HOST: ${HOST}
# port - port for HTTPs server to listen. int. Default: 8643
# PORT: 8643
AUDIT_DB_NAME: ${AUDIT_DB_NAME}
USERS_DB_NAME: ${USERS_DB_NAME}
TGOTP_DB_NAME: ${TGOTP_DB_NAME}
# https_key - private key in pem format location. Default: ./etc/cert/key.pem
KEY_PATH: ${KEY_PATH}
# https_cert - certificate in pem format location. Default: ./etc/cert/cert.pem
CERT_PATH: ${CERT_PATH}
# tg_bot_name - telegram bot name w/o @.
TG_BOT_NAME: ${TG_BOT_NAME}
TG_API_URL: ${TG_API_URL}
# source_login - login for OTP submission.
SOURCE_LOGIN: ${TGBOT_USER}
SYSLOGADDR: ${SYSLOGADDR}
tgotpbot:
SECRET:
# tg_api_key - telegram API key from BotFather. Mandatory, no working default value.
TG_API_KEY: ${TG_API_KEY}
RADIUS_SECRET: ${RADIUS_SECRET}
# source_password- password for OTP submission. Default: hag
SOURCE_PASSWORD: ${TGBOT_PASS}
VAR:
TZ: ${TIMEZONE}
# tg_bot_name - telegram bot name w/o @. Default: PSOTPBot
TG_BOT_NAME: ${TG_BOT_NAME}
# source_login - login for request submission.
SOURCE_LOGIN: ${TGBOT_USER}
OTP_LIFETIME: 120
LOGLEVEL: info
LOGFORMAT: json
SYSLOGADDR: ${SYSLOGADDR}
SYSLOGPROTO: udp
# If exposed to outer network, user:pass is mandatory. If docker overlay network is used without exposure use user:pass at own discretion.
#
MONGO_URI: "{DB_URL}"
log:
VAR:
TZ: ${TIMEZONE}
DB_URL: ${DB_URL}
DB_SHARDED: ${DB_SHARDED}
radius:
SECRET:
RADIUS_SECRET: ${RADIUS_SECRET}
# If you plan to use EAP
#DOMAIN_USER: "domain_user"
#DOMAIN_LDAP_USER: "CN=ldap,CN=Users,DC=domain,DC=local"
#DOMAIN_PASS: "domain_password"
TGBOT_USER: ${TGBOT_USER}
TGBOT_PASS: ${TGBOT_PASS}
VAR:
TZ: ${TIMEZONE}
TGBOT_OTP_MESSAGE: "Your OTP: "
ADC_HOST: "host.domain.local"
DOMAIN_NAME: "domain.local"
ADC_REALM: "DOMAIN.LOCAL"
DOMAIN_OU: "dc=domain,dc=local"
WORKGROUP: "DOMAIN"
ADC_IP: "10.0.0.3"
RADIUS_LDAP_FILTER: "(&(objectCategory=person)(objectClass=user)( | (userprincipalname=%{User-Name})(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}) ))"
RADIUS_LDAP_TGBOT_DYNAUTH_FILTER: "(&(objectCategory=person)(objectClass=user)( | (userprincipalname=%{User-Name})(sAMAccountName=%{%{Stripped-User-Name}:-%{User-Name}}) ))"
TGBOT_NAS_IP_PREFIX: "System_at_"
Config file access.yaml used as configuration clients credentials container. It is necessary to authenticate different services to securely distribute not only normal configuration, but also secret values like keys or passwords.
adfadmin:
login: "adfadmin"
password: "nahCoBieReum2Re7vahqueeba4oMam9r"
tgotpbot:
login: "tgotpbot"
password: "quieX3aeLee9baitahNeeD0ieshae5oh"
log:
login: "log"
password: "anga0eiBohreit0eewieNgaerieghaye"
radius:
login: "radius"
password: "XohGhooBeihechivie3ouyaegaLah6ah"
# Optional:
# backup:
# login: "backup"
# password: "aK3Iugh1quaimie3leiNgeeveen7aeng"
# proxy:
# login: "proxy"
# password: "Yoo6eiGahj9aalohdoosh7biebuugh2h"
Mount cert and key in conf container:
/opt/conf/cert/cert.pem
/opt/conf/cert/key.pem
you will need to add the CA certificate to the trusted in each of the containers with adfconfcli