Skip to content
Merged
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
52 changes: 49 additions & 3 deletions .package/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ services:
- "53:53/udp"
- "80:80"
- "389:389"
- "3268:3268"
- "3269:3269"
- "443:443"
- "464:464"
- "636:636"
Expand Down Expand Up @@ -67,8 +69,6 @@ services:
depends_on:
- api_server



migrations:
image: ghcr.io/multidirectorylab/multidirectory:${VERSION:-latest}
container_name: multidirectory_migrations
Expand Down Expand Up @@ -127,7 +127,7 @@ services:
- traefik.tcp.routers.ldaps.tls.certResolver=md-resolver
- traefik.tcp.services.ldaps.loadbalancer.server.port=636
- traefik.tcp.services.ldaps.loadbalancer.proxyprotocol.version=2

cldap_server:
image: ghcr.io/multidirectorylab/multidirectory:${VERSION:-latest}
restart: unless-stopped
Expand Down Expand Up @@ -155,6 +155,52 @@ services:
- traefik.udp.routers.cldap.service=cldap
- traefik.udp.services.cldap.loadbalancer.server.port=389

global_ldap_server:
image: ghcr.io/multidirectorylab/multidirectory:${VERSION:-latest}
restart: unless-stopped
deploy:
mode: replicated
replicas: 2
endpoint_mode: dnsrr
resources:
reservations:
cpus: "0.25"
memory: 100M
environment:
- SERVICE_NAME=global_ldap_server
volumes:
- ./app:/app
- ./certs:/certs
- ldap_keytab:/LDAP_keytab/
env_file: local.env
command: python -OO multidirectory.py --global_ldap_server
tty: true
depends_on:
migrations:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "nc -zv 127.0.0.1 3268 3269"]
interval: 30s
timeout: 10s
retries: 10
start_period: 3s
labels:
- traefik.enable=true

- traefik.tcp.routers.global_ldap.rule=HostSNI(`*`)
- traefik.tcp.routers.global_ldap.entrypoints=global_ldap
- traefik.tcp.routers.global_ldap.service=global_ldap
- traefik.tcp.services.global_ldap.loadbalancer.server.port=3268
- traefik.tcp.services.global_ldap.loadbalancer.proxyprotocol.version=2

- traefik.tcp.routers.global_ldap_tls.rule=HostSNI(`*`)
- traefik.tcp.routers.global_ldap_tls.entrypoints=global_ldap_tls
- traefik.tcp.routers.global_ldap_tls.service=global_ldap_tls
- traefik.tcp.routers.global_ldap_tls.tls=true
- traefik.tcp.routers.global_ldap_tls.tls.certresolver=md-resolver
- traefik.tcp.services.global_ldap_tls.loadbalancer.server.port=3269
- traefik.tcp.services.global_ldap_tls.loadbalancer.proxyprotocol.version=2

api_server:
image: ghcr.io/multidirectorylab/multidirectory:${VERSION:-latest}
container_name: multidirectory_api
Expand Down
8 changes: 8 additions & 0 deletions .package/traefik.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ entryPoints:
address: ":389"
proxyProtocol:
insecure: true
global_ldap:
address: ":3268"
proxyProtocol:
insecure: true
global_ldap_tls:
address: ":3269"
proxyProtocol:
insecure: true
ldaps:
address: ":636"
proxyProtocol:
Expand Down
19 changes: 19 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class Settings(BaseModel):
PORT: int = 389
TLS_PORT: int = 636
HTTP_PORT: int = 8000
GLOBAL_LDAP_PORT: int = 3268
GLOBAL_LDAP_TLS_PORT: int = 3269
USE_CORE_TLS: bool = False
LDAP_LOAD_SSL_CERT: bool = False

Expand Down Expand Up @@ -197,6 +199,23 @@ def get_copy_4_tls(self) -> "Settings":
tls_settings.PORT = tls_settings.TLS_PORT
return tls_settings

def get_copy_4_global(self) -> "Settings":
"""Create a copy for global LDAP server."""
from copy import copy

global_settings = copy(self)
global_settings.PORT = global_settings.GLOBAL_LDAP_PORT
return global_settings

def get_copy_4_global_tls(self) -> "Settings":
"""Create a copy for global LDAP server with TLS."""
from copy import copy

global_tls_settings = copy(self)
global_tls_settings.USE_CORE_TLS = True
global_tls_settings.PORT = global_tls_settings.GLOBAL_LDAP_TLS_PORT
return global_tls_settings

def check_certs_exist(self) -> bool:
"""Check if certs exist."""
return os.path.exists(self.SSL_CERT) and os.path.exists(self.SSL_KEY)
Expand Down
40 changes: 40 additions & 0 deletions app/ioc.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,46 @@ async def get_session(
await session.disconnect()


class GlobalLDAPServerProvider(Provider):
"""Provider with session scope."""

scope = Scope.SESSION

@provide(scope=Scope.SESSION, provides=LDAPSession)
async def get_session(
self,
storage: SessionStorage,
) -> AsyncIterator[LDAPSession]:
"""Create ldap session."""
session = LDAPSession(storage=storage)
await session.start()
yield session
await session.disconnect()

bind_request_context = provide(
LDAPBindRequestContext,
scope=Scope.REQUEST,
)
search_request_context = provide(
LDAPSearchRequestContext,
scope=Scope.REQUEST,
)
unbind_request_context = provide(
LDAPUnbindRequestContext,
scope=Scope.REQUEST,
)

network_policy_validator = provide(
NetworkPolicyValidatorGateway,
provides=NetworkPolicyValidatorProtocol,
scope=Scope.REQUEST,
)
network_policy_validator_use_case = provide(
NetworkPolicyValidatorUseCase,
scope=Scope.REQUEST,
)


class MFACredsProvider(Provider):
"""Creds provider."""

Expand Down
37 changes: 36 additions & 1 deletion app/multidirectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from extra.dump_acme_certs import dump_acme_cert
from ioc import (
EventSenderProvider,
GlobalLDAPServerProvider,
HTTPProvider,
LDAPServerProvider,
MainProvider,
Expand Down Expand Up @@ -214,6 +215,28 @@ async def cldap_factory(settings: Settings) -> None:
await CLDAPUDPServer(settings, container).start()


async def global_ldap_server_factory(settings: Settings) -> None:
"""Run global_ldap_server_factory."""
servers = []

for setting in (
settings.get_copy_4_global(),
settings.get_copy_4_global_tls(),
):
container = make_async_container(
GlobalLDAPServerProvider(),
MainProvider(),
MFAProvider(),
MFACredsProvider(),
context={Settings: setting},
)

settings = await container.get(Settings)
servers.append(PoolClientHandler(settings, container).start())

await asyncio.gather(*servers)


async def event_handler_factory(settings: Settings) -> None:
"""Run event handler."""
main_container = make_async_container(
Expand Down Expand Up @@ -244,6 +267,10 @@ async def event_sender_factory(settings: Settings) -> None:

ldap = partial(run_entrypoint, factory=ldap_factory)
cldap = partial(run_entrypoint, factory=cldap_factory)
global_ldap_server = partial(
run_entrypoint,
factory=global_ldap_server_factory,
)
scheduler = partial(run_entrypoint, factory=scheduler_factory)
create_shadow_app = partial(create_prod_app, factory=_create_shadow_app)
event_handler = partial(run_entrypoint, factory=event_handler_factory)
Expand All @@ -257,6 +284,11 @@ async def event_sender_factory(settings: Settings) -> None:
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--ldap", action="store_true", help="Run ldap")
group.add_argument("--cldap", action="store_true", help="Run cldap")
group.add_argument(
"--global_ldap_server",
action="store_true",
help="Run global_ldap_server",
)
group.add_argument("--http", action="store_true", help="Run http")
group.add_argument("--shadow", action="store_true", help="Run http")
group.add_argument("--scheduler", action="store_true", help="Run tasks")
Expand Down Expand Up @@ -286,9 +318,12 @@ async def event_sender_factory(settings: Settings) -> None:
if args.ldap:
ldap(settings=settings)

if args.cldap:
elif args.cldap:
cldap(settings=settings)

elif args.global_ldap_server:
global_ldap_server(settings=settings)

elif args.event_sender:
event_sender(settings=settings)

Expand Down
57 changes: 55 additions & 2 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,59 @@ services:
- traefik.udp.routers.cldap.service=cldap
- traefik.udp.services.cldap.loadbalancer.server.port=389

global_ldap_server:
image: multidirectory
restart: unless-stopped
build:
context: .
dockerfile: ./.docker/dev.Dockerfile
args:
DOCKER_BUILDKIT: 1
target: runtime
deploy:
mode: replicated
replicas: 2
endpoint_mode: dnsrr
resources:
reservations:
cpus: "0.25"
memory: 100M
environment:
- SERVICE_NAME=global_ldap_server
volumes:
- ./app:/app
- ./certs:/certs
- ldap_keytab:/LDAP_keytab/
env_file: local.env
command: python -OO multidirectory.py --global_ldap_server
tty: true
depends_on:
migrations:
condition: service_completed_successfully
cert_local_check:
condition: service_completed_successfully
healthcheck:
test: ["CMD-SHELL", "nc -zv 127.0.0.1 3268 3269"]
interval: 30s
timeout: 10s
retries: 10
start_period: 3s
labels:
- traefik.enable=true

- traefik.tcp.routers.global_ldap.rule=HostSNI(`*`)
- traefik.tcp.routers.global_ldap.entrypoints=global_ldap
- traefik.tcp.routers.global_ldap.service=global_ldap
- traefik.tcp.services.global_ldap.loadbalancer.server.port=3268
- traefik.tcp.services.global_ldap.loadbalancer.proxyprotocol.version=2

- traefik.tcp.routers.global_ldap_tls.rule=HostSNI(`*`)
- traefik.tcp.routers.global_ldap_tls.entrypoints=global_ldap_tls
- traefik.tcp.routers.global_ldap_tls.service=global_ldap_tls
- traefik.tcp.routers.global_ldap_tls.tls=true
- traefik.tcp.routers.global_ldap_tls.tls.certresolver=md-resolver
- traefik.tcp.services.global_ldap_tls.loadbalancer.server.port=3269
- traefik.tcp.services.global_ldap_tls.loadbalancer.proxyprotocol.version=2

cert_local_check:
image: multidirectory
Expand Down Expand Up @@ -313,7 +366,7 @@ services:
condition: service_healthy
restart: true
command: krb5kdc -n

ports:
- "88:88"
- "88:88/udp"
Expand Down Expand Up @@ -447,4 +500,4 @@ volumes:
dns_server_file:
dns_server_config:
ldap_keytab:
dragonflydata:
dragonflydata:
Loading