Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8dc358ded5 | |||
| 326895dffd | |||
| 6b0742634c | |||
| 45564fa83e | |||
| 162951d6dd | |||
| d3c54dd9bc | |||
| 512f07eb25 | |||
| 8beb4b6055 |
29
docker-compose.yml
Normal file
29
docker-compose.yml
Normal file
@ -0,0 +1,29 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ldap:
|
||||
# Tells Compose to build the image from the Dockerfile in the current directory
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
- LDAP_HOST=example.com
|
||||
image: ldapdock
|
||||
container_name: ldapdock
|
||||
hostname: example.com
|
||||
stdin_open: true # Equivalent of -i
|
||||
tty: true # Equivalent of -t
|
||||
ports:
|
||||
- "389:389"
|
||||
- "636:636"
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ldap_data:/var/lib/ldap
|
||||
- ldap_config:/etc/ldap/slapd.d
|
||||
- ldap_certs:/etc/ldap/certs
|
||||
- ./hosts-certs:/export-certs
|
||||
|
||||
volumes:
|
||||
ldap_data:
|
||||
ldap_config:
|
||||
ldap_certs:
|
||||
29
dockerfile
29
dockerfile
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:22.04
|
||||
FROM debian:12
|
||||
|
||||
# set container hostname and DN in case we don't set it on the docker build/run command
|
||||
ARG LDAP_HOST=example.com
|
||||
@ -6,20 +6,25 @@ ENV LDAP_HOST=${LDAP_HOST}
|
||||
|
||||
# set non-interactive TERM for docker
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
#──────────────────────────────────────────────────────────────
|
||||
# install OpenLDAP, ldap-utils, and packages needed for ldapdock to work
|
||||
#──────────────────────────────────────────────────────────────
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
slapd ldap-utils gnutls-bin ssl-cert ca-certificates schema2ldif vim mc && apt-get clean
|
||||
|
||||
#──────────────────────────────────────────────────────────────
|
||||
# APACHE && PHP && neccesary related software
|
||||
# Install ALL necessary packages in a single run for minimal image size
|
||||
#──────────────────────────────────────────────────────────────
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
apache2 \
|
||||
php libapache2-mod-php \
|
||||
php-ldap php-mbstring php-xml php-curl php-intl wget \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends gnupg lsb-release ca-certificates apt-transport-https software-properties-common wget curl \
|
||||
# Add the Ondřej Surý PHP repository (modern Debian way)
|
||||
&& wget -qO- https://packages.sury.org/php/apt.gpg | gpg --dearmor -o /usr/share/keyrings/sury-php-archive-keyring.gpg \
|
||||
&& echo "deb [signed-by=/usr/share/keyrings/sury-php-archive-keyring.gpg] https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list \
|
||||
# Update package lists again to include the new PHP repo
|
||||
&& apt-get update \
|
||||
# Install all required packages, using PHP 8.1 from the Surý repo
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
apt-utils \
|
||||
slapd ldap-utils gnutls-bin ssl-cert schema2ldif vim mc \
|
||||
apache2 \
|
||||
php8.1 libapache2-mod-php8.1 \
|
||||
php8.1-ldap php8.1-mbstring php8.1-xml php8.1-curl php8.1-intl \
|
||||
# Clean up APT caches to keep the image small
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Enable required Apache modules
|
||||
RUN a2enmod rewrite headers ssl
|
||||
|
||||
@ -37,7 +37,8 @@ slapd -h "ldap:/// ldapi:///" -u openldap -g openldap &
|
||||
SLAPD_PID=$!
|
||||
sleep 8
|
||||
|
||||
# Full tree with root entry
|
||||
# Full tree with root and users entries
|
||||
echo "--> Creating base.ldif with root and user entries"
|
||||
cat > /tmp/base.ldif <<EOF
|
||||
dn: ${LDAP_BASE_DN}
|
||||
objectClass: top
|
||||
@ -75,9 +76,98 @@ homeDirectory: /home/marisa
|
||||
gecos: Marisa Kirisame
|
||||
EOF
|
||||
|
||||
# Create phplogin.php with dynamic base DN
|
||||
echo "--> Creating phplogin.php with full users support"
|
||||
cat > /var/www/html/phplogin.php <<'EOF'
|
||||
<?php
|
||||
// Use the same logic as entrypoint.sh, but with better localhost handling
|
||||
$raw_host = $_SERVER['HTTP_HOST'] ?? 'example.com';
|
||||
$raw_host = preg_replace('/:\d+$/', '', $raw_host); // strip port if present
|
||||
|
||||
if ($raw_host === 'localhost' || $raw_host === '127.0.0.1') {
|
||||
// When testing locally via http://localhost → assume default example.com
|
||||
$base_dn = 'dc=example,dc=com';
|
||||
} else {
|
||||
// Normal case: build dc=... from real hostname
|
||||
$host_parts = explode('.', $raw_host);
|
||||
$base_dn = '';
|
||||
foreach ($host_parts as $part) {
|
||||
if ($part) $base_dn .= ($base_dn ? ',' : '') . 'dc=' . $part;
|
||||
}
|
||||
if (!$base_dn) $base_dn = 'dc=example,dc=com'; // ultimate fallback
|
||||
}
|
||||
|
||||
$msg = '';
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$username = trim($_POST['username'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if ($username && $password) {
|
||||
$ldap = ldap_connect("ldap://127.0.0.1:389");
|
||||
if ($ldap) {
|
||||
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
if (ldap_start_tls($ldap)) {
|
||||
// First: try admin bind (no ou=People)
|
||||
$admin_dn = "cn=admin,{$base_dn}";
|
||||
if (@ldap_bind($ldap, $admin_dn, $password)) {
|
||||
$msg = "<p style='color:green;font-weight:bold'>Login successful! Welcome <strong>admin</strong> (full privileges)</p>";
|
||||
}
|
||||
// Second: if not admin, try regular user
|
||||
elseif (@ldap_bind($ldap, "uid={$username},ou=People,{$base_dn}", $password)) {
|
||||
$msg = "<p style='color:green;font-weight:bold'>Login successful! Welcome {$username}</p>";
|
||||
}
|
||||
else {
|
||||
$msg = "<p style='color:red'>Invalid credentials</p>";
|
||||
}
|
||||
} else {
|
||||
$msg = "<p style='color:red'>StartTLS failed</p>";
|
||||
}
|
||||
ldap_close($ldap);
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Could not connect to LDAP server</p>";
|
||||
}
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Please fill both fields</p>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ldapdock LDAP login</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; text-align: center; }
|
||||
input, button { padding: 10px; margin: 5px; width: 100%; font-size: 16px; box-sizing: border-box; }
|
||||
button { background: #007cba; color: white; border: none; cursor: pointer; }
|
||||
.note { font-size: 0.9em; color: #666; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ldapdock login</h1>
|
||||
<p>Server base DN: <strong><?= htmlspecialchars($base_dn) ?></strong></p>
|
||||
<?= $msg ?>
|
||||
<form method="post">
|
||||
<input type="text" name="username" placeholder="Username (marisa or admin)" required autofocus>
|
||||
<input type="password" name="password" placeholder="Password" required>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<hr>
|
||||
<div class="note">
|
||||
<strong>Test accounts:</strong><br>
|
||||
Regular user: <code>marisa</code> / password: <code>MarisaNewPass2025</code><br>
|
||||
Admin user: <code>admin</code> / password: <code>admin</code>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
ADMIN_DN="cn=admin,${LDAP_BASE_DN}"
|
||||
ADMIN_PW="admin"
|
||||
|
||||
echo "--> Adding base structure"
|
||||
ldapadd -c -x -D "cn=admin,dc=example,dc=com" -w admin -f /tmp/base.ldif || true
|
||||
ldapadd -c -x -D "$ADMIN_DN" -w "$ADMIN_PW" -f /tmp/base.ldif || true
|
||||
|
||||
#──────────────────────────────────────────────────────────────
|
||||
# TLS BLOCK
|
||||
@ -158,8 +248,6 @@ fi
|
||||
|
||||
# Set Marisa password (full LDIF — so ldapmodify knows what to modify)
|
||||
echo "--> Setting Marisa password to 'MarisaNewPass2025' using Admin Bind"
|
||||
ADMIN_DN="cn=admin,${LDAP_BASE_DN}"
|
||||
ADMIN_PW="admin"
|
||||
slappasswd -h '{SSHA}' -s MarisaNewPass2025 | \
|
||||
ldapmodify -x -D "$ADMIN_DN" -w "$ADMIN_PW" <<EOF >/dev/null 2>&1
|
||||
dn: uid=marisa,ou=People,${LDAP_BASE_DN}
|
||||
@ -272,6 +360,7 @@ fi
|
||||
echo "--> ldapdock ready — OpenLDAP + Apache + PHP running"
|
||||
echo " → LDAP: 389/636"
|
||||
echo " → PHPinfo: https://localhost/info.php"
|
||||
echo " → PHPlogin test: https://localhost/phplogin.php"
|
||||
echo " → Shell: /bin/bash"
|
||||
echo " → Exit with CTRL+D or 'exit' command"
|
||||
|
||||
|
||||
54
index.php
54
index.php
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
$host = $_SERVER['HTTP_HOST']; // works for example.com or any LDAP_HOST
|
||||
$msg = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$uid = trim($_POST['uid'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if ($uid && $password) {
|
||||
$ldap = ldap_connect("ldap://127.0.0.1:389");
|
||||
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
// StartTLS – required because your OpenLDAP enforces it
|
||||
if (ldap_start_tls($ldap)) {
|
||||
$bind_dn = "uid=$uid,ou=People,dc=$host";
|
||||
if (@ldap_bind($ldap, $bind_dn, $password)) {
|
||||
$msg = "<p style='color:green;font-weight:bold'>Login successful! Welcome $uid</p>";
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Invalid credentials</p>";
|
||||
}
|
||||
} else {
|
||||
$msg = "<p style='color:red'>TLS failure</p>";
|
||||
}
|
||||
ldap_close($ldap);
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Please fill both fields</p>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ldapdock – LDAP login</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; text-align: center; }
|
||||
input, button { padding: 10px; margin: 5px; width: 100%; font-size: 16px; }
|
||||
button { background: #007cba; color: white; cursor: pointer; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ldapdock login</h1>
|
||||
<p>Server: <strong><?= htmlspecialchars($host) ?></strong></p>
|
||||
<?= $msg ?>
|
||||
<form method="post">
|
||||
<input type="text" name="uid" placeholder="uid (e.g. marisa)" required autofocus><br>
|
||||
<input type="password" name="password" placeholder="password" required><br>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<hr>
|
||||
<small>Test user: marisa / qwerty</small>
|
||||
</body>
|
||||
</html>
|
||||
54
phplogin.php
Normal file
54
phplogin.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
$host = $_SERVER['HTTP_HOST']; // works for example.com or any LDAP_HOST
|
||||
$msg = '';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$uid = trim($_POST['uid'] ?? '');
|
||||
$password = $_POST['password'] ?? '';
|
||||
|
||||
if ($uid && $password) {
|
||||
$ldap = ldap_connect("ldap://127.0.0.1:389");
|
||||
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
|
||||
|
||||
// StartTLS required because your OpenLDAP enforces it
|
||||
if (ldap_start_tls($ldap)) {
|
||||
$bind_dn = "$uid,dc=example,dc=com";
|
||||
if (@ldap_bind($ldap, $bind_dn, $password)) {
|
||||
$msg = "<p style='color:green;font-weight:bold'>Login successful! Welcome $uid</p>";
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Invalid credentials</p>$bind_dn";
|
||||
}
|
||||
} else {
|
||||
$msg = "<p style='color:red'>TLS failure</p>";
|
||||
}
|
||||
ldap_close($ldap);
|
||||
} else {
|
||||
$msg = "<p style='color:red'>Please fill both fields</p>";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>ldapdock LDAP login</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; text-align: center; }
|
||||
input, button { padding: 10px; margin: 5px; width: 100%; font-size: 16px; }
|
||||
button { background: #007cba; color: white; cursor: pointer; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>ldapdock login</h1>
|
||||
<p>Server: <strong><?= htmlspecialchars($host) ?></strong></p>
|
||||
<?= $msg ?>
|
||||
<form method="post">
|
||||
<input type="text" name="uid" placeholder="uid (e.g. marisa)" required autofocus><br>
|
||||
<input type="password" name="password" placeholder="password" required><br>
|
||||
<button type="submit">Login</button>
|
||||
</form>
|
||||
<hr>
|
||||
<small>Test user: uid=marisa,ou=People / MarisaNewPass2025</small>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user