fix ftp proxy (vip)

This commit is contained in:
2025-11-01 21:31:20 +01:00
parent 37db980c10
commit 20a99aea9c
4 changed files with 177 additions and 10 deletions

70
.env.example Normal file
View File

@@ -0,0 +1,70 @@
# ASE Application - Environment Variables
# Copia questo file in .env e modifica i valori secondo le tue necessità
# ============================================================================
# FTP Server Configuration
# ============================================================================
# Porta iniziale del range di porte passive FTP
# Il range completo sarà FTP_PASSIVE_PORTS to (FTP_PASSIVE_PORTS + portRangeWidth - 1)
# Default: valore da ftp.ini
FTP_PASSIVE_PORTS=60000
# IP esterno da pubblicizzare ai client FTP (importante per HA con VIP)
# Questo è l'indirizzo che i client useranno per connettersi in modalità passiva
# In un setup HA, questo dovrebbe essere il VIP condiviso tra le istanze
# Default: valore da ftp.ini
FTP_EXTERNAL_IP=192.168.1.100
# ============================================================================
# Database Configuration
# ============================================================================
# Hostname del server MySQL
# Default: valore da db.ini
DB_HOST=localhost
# Porta del server MySQL
# Default: valore da db.ini
DB_PORT=3306
# Username per la connessione al database
# Default: valore da db.ini
DB_USER=ase_user
# Password per la connessione al database
# Default: valore da db.ini
DB_PASSWORD=your_secure_password
# Nome del database
# Default: valore da db.ini
DB_NAME=ase_lar
# ============================================================================
# Logging Configuration
# ============================================================================
# Livello di logging: DEBUG, INFO, WARNING, ERROR, CRITICAL
# Default: INFO
LOG_LEVEL=INFO
# ============================================================================
# Note per Docker Compose
# ============================================================================
#
# 1. Le variabili d'ambiente OVERRIDE i valori nei file .ini
# 2. Se una variabile non è impostata, viene usato il valore dal file .ini
# 3. Questo permette deployment flessibili senza modificare i file .ini
#
# Esempio di uso in docker-compose.yml:
#
# environment:
# FTP_PASSIVE_PORTS: "${FTP_PASSIVE_PORTS:-60000}"
# FTP_EXTERNAL_IP: "${FTP_EXTERNAL_IP}"
# DB_HOST: "${DB_HOST}"
# DB_PASSWORD: "${DB_PASSWORD}"
#
# Oppure usando env_file:
#
# env_file:
# - .env

View File

@@ -0,0 +1,80 @@
version: '3.8'
services:
ftp-server:
build: .
container_name: ase-ftp-server
ports:
- "2121:2121" # FTP control port
- "60000-60099:60000-60099" # FTP passive ports range
environment:
# FTP Configuration
FTP_PASSIVE_PORTS: "60000" # Prima porta del range passivo
FTP_EXTERNAL_IP: "192.168.1.100" # IP esterno/VIP da pubblicizzare ai client
# Database Configuration
DB_HOST: "mysql-server"
DB_PORT: "3306"
DB_USER: "ase_user"
DB_PASSWORD: "your_secure_password"
DB_NAME: "ase_lar"
# Logging (opzionale)
LOG_LEVEL: "INFO"
volumes:
- ./logs:/app/logs
- ./data:/app/data
depends_on:
- mysql-server
restart: unless-stopped
networks:
- ase-network
# Esempio di setup HA con più istanze FTP
ftp-server-2:
build: .
container_name: ase-ftp-server-2
ports:
- "2122:2121" # Diversa porta di controllo per seconda istanza
- "61000-61099:60000-60099" # Diverso range passivo
environment:
FTP_PASSIVE_PORTS: "60000" # Stessa config, ma mappata su porte diverse dell'host
FTP_EXTERNAL_IP: "192.168.1.100" # Stesso VIP condiviso
DB_HOST: "mysql-server"
DB_PORT: "3306"
DB_USER: "ase_user"
DB_PASSWORD: "your_secure_password"
DB_NAME: "ase_lar"
LOG_LEVEL: "INFO"
volumes:
- ./logs2:/app/logs
- ./data:/app/data
depends_on:
- mysql-server
restart: unless-stopped
networks:
- ase-network
mysql-server:
image: mysql:8.0
container_name: ase-mysql
environment:
MYSQL_ROOT_PASSWORD: "root_password"
MYSQL_DATABASE: "ase_lar"
MYSQL_USER: "ase_user"
MYSQL_PASSWORD: "your_secure_password"
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
- ./dbddl:/docker-entrypoint-initdb.d
restart: unless-stopped
networks:
- ase-network
networks:
ase-network:
driver: bridge
volumes:
mysql-data:

View File

@@ -155,13 +155,23 @@ def main():
handler = ASEHandler
handler.cfg = cfg
handler.authorizer = authorizer
handler.masquerade_address = cfg.proxyaddr
# Set masquerade address only if configured (importante per HA con VIP)
# Questo è l'IP che il server FTP pubblicherà ai client per le connessioni passive
if cfg.proxyaddr and cfg.proxyaddr.strip():
handler.masquerade_address = cfg.proxyaddr
logger.info(f"FTP masquerade address configured: {cfg.proxyaddr}")
else:
logger.info("FTP masquerade address not configured - using server's default IP")
# Set the range of passive ports for the FTP server
_range = list(range(cfg.firstport, cfg.firstport + cfg.portrangewidth))
handler.passive_ports = _range
# Log configuration
logger.info(f"Starting FTP server on port {cfg.service_port} with DatabaseAuthorizer")
logger.info(f"FTP passive ports range: {cfg.firstport}-{cfg.firstport + cfg.portrangewidth - 1}")
logger.info(f"Database connection: {cfg.dbuser}@{cfg.dbhost}:{cfg.dbport}/{cfg.dbname}")
# Create and start the FTP server
server = FTPServer(("0.0.0.0", cfg.service_port), handler)

View File

@@ -1,5 +1,6 @@
"""set configurations"""
import os
from configparser import ConfigParser
from . import ENV_PARENT_PATH
@@ -10,15 +11,21 @@ class Config:
"""
Initializes the Config class by reading configuration files.
It loads settings from 'ftp.ini' and 'db.ini' for FTP server, CSV, logging, and database.
Environment variables override INI file settings for Docker deployments.
"""
c = ConfigParser()
c.read([f"{ENV_PARENT_PATH}/env/ftp.ini", f"{ENV_PARENT_PATH}/env/db.ini"])
# FTP setting
# FTP setting (with environment variable override for Docker)
self.service_port = c.getint("ftpserver", "service_port")
self.firstport = c.getint("ftpserver", "firstPort")
self.proxyaddr = c.get("ftpserver", "proxyAddr")
# FTP_PASSIVE_PORTS: override della porta iniziale del range passivo
self.firstport = int(os.getenv("FTP_PASSIVE_PORTS", c.getint("ftpserver", "firstPort")))
# FTP_EXTERNAL_IP: override dell'IP pubblicizzato (VIP per HA)
self.proxyaddr = os.getenv("FTP_EXTERNAL_IP", c.get("ftpserver", "proxyAddr"))
self.portrangewidth = c.getint("ftpserver", "portRangeWidth")
self.virtpath = c.get("ftpserver", "virtpath")
self.adminuser = c.get("ftpserver", "adminuser").split("|")
@@ -33,12 +40,12 @@ class Config:
# LOG setting
self.logfilename = c.get("logging", "logFilename")
# DB setting
self.dbhost = c.get("db", "hostname")
self.dbport = c.getint("db", "port")
self.dbuser = c.get("db", "user")
self.dbpass = c.get("db", "password")
self.dbname = c.get("db", "dbName")
# DB setting (with environment variable override for Docker)
self.dbhost = os.getenv("DB_HOST", c.get("db", "hostname"))
self.dbport = int(os.getenv("DB_PORT", c.getint("db", "port")))
self.dbuser = os.getenv("DB_USER", c.get("db", "user"))
self.dbpass = os.getenv("DB_PASSWORD", c.get("db", "password"))
self.dbname = os.getenv("DB_NAME", c.get("db", "dbName"))
self.max_retries = c.getint("db", "maxRetries")
# Tables