Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# docker environment overrides
# Timezone (set to your preferred TZ)
TZ=Europe/Madrid

# MariaDB settings (change as needed)
MYSQL_HOST=radius-mysql
MYSQL_PORT=3306
MYSQL_DATABASE=radius
MYSQL_USER=radius

# daloRADIUS optional settings
DEFAULT_CLIENT_SECRET=testing123
DEFAULT_FREERADIUS_SERVER=radius
MAIL_SMTPADDR=127.0.0.1
MAIL_PORT=25
MAIL_FROM=root@daloradius.xdsl.by
MAIL_AUTH=

# MySQL TLS mode: SKIP | DISABLED | PREFERRED | REQUIRED
# Default is PREFERRED (try TLS, fallback if not available)
MYSQL_SSL_MODE=PREFERRED
# Set to SKIP to explicitly disable SSL (not recommended)
# MYSQL_SSL_MODE=SKIP

# If you use Docker secrets, place files under /run/secrets with names:
# - mysql_root_password
# - mysql_password
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# docker environment overrides
# Timezone (set to your preferred TZ)
TZ=Europe/Madrid

# MariaDB settings (change as needed)
MYSQL_HOST=radius-mysql
MYSQL_PORT=3306
MYSQL_DATABASE=radius
MYSQL_USER=radius

# daloRADIUS optional settings
DEFAULT_CLIENT_SECRET=testing123
DEFAULT_FREERADIUS_SERVER=radius
MAIL_SMTPADDR=127.0.0.1
MAIL_PORT=25
MAIL_FROM=root@daloradius.xdsl.by
MAIL_AUTH=

# MySQL TLS mode: SKIP | DISABLED | PREFERRED | REQUIRED
# Default is PREFERRED (try TLS, fallback if not available)
MYSQL_SSL_MODE=PREFERRED
# Set to SKIP to explicitly disable SSL (not recommended)
# MYSQL_SSL_MODE=SKIP

# If you use Docker secrets, place files under /run/secrets with names:
# - mysql_root_password
# - mysql_password
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
.idea/
..idea/
*.log
*.db
invoice_preview.html
.DS_Store
data/
internal_data/

# Local environment overrides (do not commit secrets)
.env

# Secrets directory - contains sensitive files, do NOT commit
/secrets/*
!secrets/README.md

var/log/*.log
var/backup/*.sql
app/common/includes/daloradius.conf.php
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ RUN chown -R www-data:www-data /var/www/daloradius
RUN rm -rf /var/www/html
#
# Create daloRADIUS Log file
RUN touch /tmp/daloradius.log && chown -R www-data:www-data /tmp/daloradius.log
RUN touch /var/log/freeradius/daloradius.log && chown -R www-data:www-data /var/log/freeradius/daloradius.log
RUN mkdir -p /var/log/apache2/daloradius && chown -R www-data:www-data /var/log/apache2/daloradius
RUN echo "Mutex posixsem" >> /etc/apache2/apache2.conf

Expand Down
29 changes: 25 additions & 4 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
version: "3"

services:

radius-mysql:
image: mariadb:10
container_name: radius-mysql
restart: unless-stopped
# Expose MariaDB port only if you need host access (e.g., external backups or admin tools).
# Leaving this commented keeps the DB accessible only on the Docker network (safer).
# To enable host access, uncomment and secure it with firewall rules:
# Expose MariaDB to the host *only* if you need external access (e.g., backups or admin tools).
# By default this is commented so the DB is only accessible on the Docker network (safer).
# To expose the DB port to the host, uncomment and secure with firewall rules:
ports:
- '3306:3306'
environment:
- MYSQL_DATABASE=radius
- MYSQL_USER=radius
- MYSQL_PASSWORD=radiusdbpw
- MYSQL_ROOT_PASSWORD=radiusrootdbpw
- MYSQL_PASSWORD_FILE=/run/secrets/MYSQL_PASSWORD
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/MYSQL_ROOT_PASSWORD
- TZ=${TZ}
- MYSQL_CA_FILE=/etc/mysql/certs/mysql_ca.pem
secrets:
- MYSQL_ROOT_PASSWORD
- MYSQL_PASSWORD
volumes:
- "./data/mysql:/var/lib/mysql"
- mariadb_certs:/etc/mysql/certs
- ./docker/mariadb/tls.cnf:/etc/mysql/conf.d/tls.cnf:ro

radius:
container_name: radius
Expand All @@ -36,6 +49,7 @@ services:
volumes:
- ./data/freeradius:/data
- radius_logs:/var/log/freeradius
- mariadb_certs:/etc/mysql/certs
# Uncomment below to enable debug logging.
#command: -X

Expand Down Expand Up @@ -69,3 +83,10 @@ services:

volumes:
radius_logs:
Comment on lines 83 to 85
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The volumes section defines 'radius_logs' as a named volume, but the services now use bind mounts './radius_logs:/var/log/freeradius' instead. This creates an unused volume definition. Either remove the named volume definition or use it consistently in the service volume mappings.

Suggested change
volumes:
radius_logs:

Copilot uses AI. Check for mistakes.
mariadb_certs:

secrets:
MYSQL_ROOT_PASSWORD:
file: ./secrets/mysql_root_password
MYSQL_PASSWORD:
file: ./secrets/mysql_password
85 changes: 85 additions & 0 deletions docker/daloradius/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Official daloRADIUS dockerfile
# GitHub: https://github.com/lirantal/daloradius
#
# Build image:
# 1. git pull git@github.com:lirantal/daloradius.git
# 2. docker build . -t lirantal/daloradius
#
# Run the container:
# 1. docker run -p 80:80 -p 8000:8000 -d lirantal/daloradius

FROM debian:13-slim

LABEL maintainer="Liran Tal <liran.tal@gmail.com>" \
Description="daloRADIUS Official docker based on Debian 13 and PHP8." \
License="GPLv2" \
Usage="docker build . -t lirantal/daloradius && docker run -d -p 80:80 -p 8000:8000 lirantal/daloradius" \
Version="2.0beta"

ENV DEBIAN_FRONTEND noninteractive

# default timezone (overridable at runtime via docker-compose/.env)
ENV TZ=Europe/Madrid

# PHP install
RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
ca-certificates \
apt-utils \
freeradius-utils \
tzdata \
apache2 \
libapache2-mod-php \
cron \
net-tools \
php \
php-common \
php-gd \
php-cli \
php-curl \
php-mail \
php-dev \
php-mail-mime \
php-mbstring \
php-db \
php-mysql \
php-zip \
mariadb-client \
default-libmysqlclient-dev \
unzip \
wget \
dos2unix \
&& rm -rf /var/lib/apt/lists/*

ADD contrib/docker/operators.conf /etc/apache2/sites-available/operators.conf
ADD contrib/docker/users.conf /etc/apache2/sites-available/users.conf
RUN a2dissite 000-default.conf && \
a2ensite users.conf operators.conf && \
sed -i 's/Listen 80/Listen 80\nListen 8000/' /etc/apache2/ports.conf

# Create directories
# /data should be mounted as volume to avoid recreation of database entries
RUN mkdir /data
ADD . /var/www/daloradius

#RUN touch /var/www/html/library/daloradius.conf.php
RUN chown -R www-data:www-data /var/www/daloradius

# Remove the original sample web folder
RUN rm -rf /var/www/html
#
# Create daloRADIUS Log file
RUN touch /var/log/freeradius/daloradius.log && chown -R www-data:www-data /var/log/freeradius/daloradius.log
RUN mkdir -p /var/log/apache2/daloradius && chown -R www-data:www-data /var/log/apache2/daloradius
RUN echo "Mutex posixsem" >> /etc/apache2/apache2.conf

# Add init script from docker directory and make it executable
ADD docker/daloradius/init.sh /var/www/daloradius/init.sh
RUN dos2unix /var/www/daloradius/init.sh || true && chmod +x /var/www/daloradius/init.sh

## Expose Web port for daloRADIUS
EXPOSE 80
EXPOSE 8000
#
## Run the script which executes Apache2 in the foreground as a running process
CMD ["/bin/bash", "/var/www/daloradius/init.sh"]
90 changes: 90 additions & 0 deletions docker/daloradius/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash
# Executable process script for daloRADIUS docker image:
# GitHub: git@github.com:lirantal/daloradius.git
# EOL: normalized to LF
DALORADIUS_PATH=/var/www/daloradius
DALORADIUS_CONF_PATH=/var/www/daloradius/app/common/includes/daloradius.conf.php
function init_daloradius {
if ! test -f "$DALORADIUS_CONF_PATH" || ! test -s "$DALORADIUS_CONF_PATH"; then
cp "$DALORADIUS_CONF_PATH.sample" "$DALORADIUS_CONF_PATH"
chown www-data:www-data "$DALORADIUS_CONF_PATH"
fi

# Set defaults if not provided by .env (docker service names)
MYSQL_HOST=${MYSQL_HOST:-radius-mysql}
MYSQL_PORT=${MYSQL_PORT:-3306}
MYSQL_USER=${MYSQL_USER:-radius}
MYSQL_PASSWORD=${MYSQL_PASSWORD:-radiusdbpw}
MYSQL_DATABASE=${MYSQL_DATABASE:-radius}

sed -i "s/\$configValues\['CONFIG_DB_HOST'\] = .*;/\$configValues\['CONFIG_DB_HOST'\] = '$MYSQL_HOST';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['CONFIG_DB_PORT'\] = .*;/\$configValues\['CONFIG_DB_PORT'\] = '$MYSQL_PORT';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['CONFIG_DB_PASS'\] = .*;/\$configValues\['CONFIG_DB_PASS'\] = '$MYSQL_PASSWORD';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['CONFIG_DB_USER'\] = .*;/\$configValues\['CONFIG_DB_USER'\] = '$MYSQL_USER';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['CONFIG_DB_NAME'\] = .*;/\$configValues\['CONFIG_DB_NAME'\] = '$MYSQL_DATABASE';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['FREERADIUS_VERSION'\] = .*;/\$configValues\['FREERADIUS_VERSION'\] = '3';/" $DALORADIUS_CONF_PATH
sed -i "s/\$configValues\['CONFIG_DB_PASSWORD_ENCRYPTION'\] = .*;/\$configValues\['CONFIG_DB_PASSWORD_ENCRYPTION'\] = 'no';/" $DALORADIUS_CONF_PATH
[ -n "$PASSWORD_MIN_LENGTH" ] && sed -i "s/\$configValues\['CONFIG_DB_PASSWORD_MIN_LENGTH'\] = .*;/\$configValues\['CONFIG_DB_PASSWORD_MIN_LENGTH'\] = '$PASSWORD_MIN_LENGTH';/" $DALORADIUS_CONF_PATH
[ -n "$PASSWORD_MAX_LENGTH" ] && sed -i "s/\$configValues\['CONFIG_DB_PASSWORD_MAX_LENGTH'\] = .*;/\$configValues\['CONFIG_DB_PASSWORD_MAX_LENGTH'\] = '$PASSWORD_MAX_LENGTH';/" $DALORADIUS_CONF_PATH

[ -n "$DEFAULT_FREERADIUS_SERVER" ] \
&& sed -i "s/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSERVER'\] = .*;/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSERVER'\] = '$DEFAULT_FREERADIUS_SERVER';/" $DALORADIUS_CONF_PATH \
|| sed -i "s/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSERVER'\] = .*;/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSERVER'\] = 'radius';/" $DALORADIUS_CONF_PATH
[ -n "$DEFAULT_FREERADIUS_PORT" ] && sed -i "s/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSPORT'\] = .*;/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSPORT'\] = '$DEFAULT_FREERADIUS_PORT';/" $DALORADIUS_CONF_PATH
[ -n "$DEFAULT_CLIENT_SECRET" ] && sed -i "s/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSECRET'\] = .*;/\$configValues\['CONFIG_MAINT_TEST_USER_RADIUSSECRET'\] = '$DEFAULT_CLIENT_SECRET';/" $DALORADIUS_CONF_PATH

[ -n "$MAIL_SMTPADDR" ] && sed -i "s/\$configValues\['CONFIG_MAIL_SMTPADDR'\] = .*;/\$configValues\['CONFIG_MAIL_SMTPADDR'\] = '$MAIL_SMTPADDR';/" $DALORADIUS_CONF_PATH
[ -n "$MAIL_PORT" ] && sed -i "s/\$configValues\['CONFIG_MAIL_SMTPPORT'\] = .*;/\$configValues\['CONFIG_MAIL_SMTPPORT'\] = '$MAIL_PORT';/" $DALORADIUS_CONF_PATH
[ -n "$MAIL_FROM" ] && sed -i "s/\$configValues\['CONFIG_MAIL_SMTPFROM'\] = .*;/\$configValues\['CONFIG_MAIL_SMTPFROM'\] = '$MAIL_FROM';/" $DALORADIUS_CONF_PATH
[ -n "$MAIL_AUTH" ] && sed -i "s/\$configValues\['CONFIG_MAIL_SMTPAUTH'\] = .*;/\$configValues\['CONFIG_MAIL_SMTPAUTH'\] = '$MAIL_AUTH';/" $DALORADIUS_CONF_PATH
Comment on lines +20 to +39
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

init_daloradius writes environment variables (e.g. MYSQL_HOST, MYSQL_PASSWORD, mail settings, RADIUS secrets) directly into daloradius.conf.php using sed without escaping, so a value containing quotes or PHP metacharacters can break out of the string literal and inject arbitrary PHP code. If an attacker can influence any of these environment variables or the .env file (for example via misconfigured deployment tooling or compromised CI), they can achieve remote code execution as the web server user when the config file is loaded. Use a safer templating mechanism or ensure all values are properly escaped for PHP string context before being substituted into the configuration file.

Copilot uses AI. Check for mistakes.
sed -i "s/\$configValues\['CONFIG_LOG_FILE'\] = .*;/\$configValues\['CONFIG_LOG_FILE'\] = '\/tmp\/daloradius.log';/" $DALORADIUS_CONF_PATH

echo "daloRADIUS initialization completed."
}

function init_database {
# Create database if not exists
mysql -h "$MYSQL_HOST" --skip-ssl -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE DATABASE IF NOT EXISTS \`$MYSQL_DATABASE\`;"

# Create user for any host '%' and grant privileges (docker uses network connections, not localhost)
mysql -h "$MYSQL_HOST" --skip-ssl -u root -p"$MYSQL_ROOT_PASSWORD" -e "CREATE USER IF NOT EXISTS '$MYSQL_USER'@'%' IDENTIFIED BY '$MYSQL_PASSWORD';"
mysql -h "$MYSQL_HOST" --skip-ssl -u root -p"$MYSQL_ROOT_PASSWORD" -e "GRANT ALL PRIVILEGES ON \`$MYSQL_DATABASE\`.* TO '$MYSQL_USER'@'%'; FLUSH PRIVILEGES;"

# Import schema using client option to disable SSL if server does not have it
mysql --skip-ssl -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" < $DALORADIUS_PATH/contrib/db/mariadb-daloradius.sql
Comment thread
lirantal marked this conversation as resolved.
echo "Database initialization for daloRADIUS completed."
Comment on lines +47 to +55
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The daloRADIUS database initialization uses mysql/mysqladmin with the --skip-ssl flag (including root connections), which disables TLS even if the MariaDB server supports it and forces credentials and schema traffic to be sent unencrypted. Anyone able to observe traffic on the Docker or host network can capture the root and application DB passwords as well as RADIUS-related data during initialization. Remove --skip-ssl and, where possible, require TLS for client connections to MariaDB so that database credentials and data are encrypted in transit.

Copilot uses AI. Check for mistakes.
}

echo "Starting daloRADIUS..."

INIT_LOCK=/data/.init_done
if test -f "$INIT_LOCK"; then
#
if ! test -f "$DALORADIUS_CONF_PATH" || ! test -s "$DALORADIUS_CONF_PATH"; then
echo "Init lock file exists but config file does not exist or is 0 bytes, performing initial setup of daloRADIUS."
init_daloradius
fi
echo "Init lock file exists and config file exists, skipping initial setup of daloRADIUS."
else
init_daloradius
date > $INIT_LOCK
fi

# wait for MySQL-Server to be ready
echo -n "Waiting for mysql ($MYSQL_HOST)..."
# use --skip-ssl so client doesn't require TLS if server doesn't support it
while ! mysqladmin ping -h"$MYSQL_HOST" -u root -p"$MYSQL_ROOT_PASSWORD" --skip-ssl --silent; do
sleep 5
done
echo "ok"

DB_LOCK=/data/.db_init_done
if test -f "$DB_LOCK"; then
echo "Database lock file exists, skipping initial setup of mysql database."
else
init_database
date > $DB_LOCK
fi

# Start Apache2 in the foreground
/usr/sbin/apachectl -DFOREGROUND -k start
53 changes: 53 additions & 0 deletions docker/freeradius/Dockerfile-freeradius
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Official daloRADIUS dockerfile for freeradius
# GitHub: https://github.com/lirantal/daloradius
#
# Build image:
# 1. git pull git@github.com:lirantal/daloradius.git
# 2. docker build -t lirantal/daloradius -f dockerfile-freeradius
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on line 6 references 'dockerfile-freeradius' (lowercase) but the actual filename in the diff is 'Dockerfile-freeradius' (capitalized D). This inconsistency could confuse users trying to follow the build instructions.

Copilot uses AI. Check for mistakes.
#
# Run the container:
# 1. docker run -p 80:80 -d lirantal/dalofreeradius

FROM freeradius/freeradius-server:latest
MAINTAINER Liran Tal <liran.tal@gmail.com>
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The MAINTAINER instruction is deprecated in favor of LABEL maintainer="...". Consider updating to: LABEL maintainer="Liran Tal <liran.tal@gmail.com>"

Suggested change
MAINTAINER Liran Tal <liran.tal@gmail.com>
LABEL maintainer="Liran Tal <liran.tal@gmail.com>"

Copilot uses AI. Check for mistakes.

LABEL Description="freeradius docker based on Ubuntu 20.04 LTS, optimized for daloRADIUS." \
License="GPLv2" \
Usage="docker build -t lirantal/dalofreeradius -f dockerfile-freeradius && docker run -d -p 80:80 lirantal/dalofreeradius" \
Version="1.0"

ENV DEBIAN_FRONTEND noninteractive

# default timezone (overridable at runtime via docker-compose/.env)
ENV TZ=Europe/Madrid

RUN apt-get update \
&& apt-get install --yes --no-install-recommends \
apt-utils \
ipcalc \
tzdata \
net-tools \
mariadb-client \
libmysqlclient-dev \
unzip \
wget \
dos2unix \
&& rm -rf /var/lib/apt/lists/*

# Create directories
# /data should be mounted as volume to avoid recreation of database entries
RUN mkdir /app /data
WORKDIR /app

# Copy init script to image
ADD docker/freeradius/init-freeradius.sh /app

# Normalize EOL and make init.sh script executable
RUN dos2unix /app/init-freeradius.sh || true && chmod +x /app/init-freeradius.sh

# Expose FreeRADIUS Ports
EXPOSE 1812 1813

# Run the script which executes freeradius in foreground (invoke with bash to avoid CRLF shebang issues)
ENTRYPOINT ["/bin/bash", "/app/init-freeradius.sh"]
CMD ["/bin/bash", "/app/init-freeradius.sh"]
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ENTRYPOINT and CMD both specify the same script. This is redundant - when both are specified, CMD becomes arguments to ENTRYPOINT. Either use only ENTRYPOINT or only CMD. Since the script doesn't take arguments (other than freeradius flags), using only CMD would be clearer.

Suggested change
CMD ["/bin/bash", "/app/init-freeradius.sh"]

Copilot uses AI. Check for mistakes.
Loading