first commit
This commit is contained in:
40
deploy/Dockerfile
Normal file
40
deploy/Dockerfile
Normal file
@@ -0,0 +1,40 @@
|
||||
# ============================================================================
|
||||
# Образ PHP-FPM для защищённого Laravel-приложения (УЗ-1 / К1)
|
||||
# Меры: УКФ.1 (фиксированные версии), ОДТ (минимизация образа).
|
||||
# ============================================================================
|
||||
FROM php:8.3-fpm-alpine AS base
|
||||
|
||||
# Системные зависимости и расширения PHP (включая pgsql, redis, gd для проверок).
|
||||
RUN apk add --no-cache postgresql-dev oniguruma-dev icu-dev libzip-dev $PHPIZE_DEPS \
|
||||
&& docker-php-ext-install pdo_pgsql mbstring intl bcmath opcache zip \
|
||||
&& pecl install redis && docker-php-ext-enable redis \
|
||||
&& apk del $PHPIZE_DEPS
|
||||
|
||||
# Рекомендуемая базовая конфигурация PHP (УКФ.1, ОДТ.3).
|
||||
RUN { \
|
||||
echo 'expose_php=Off'; \
|
||||
echo 'display_errors=Off'; \
|
||||
echo 'log_errors=On'; \
|
||||
echo 'session.cookie_httponly=On'; \
|
||||
echo 'session.cookie_secure=On'; \
|
||||
echo 'session.use_strict_mode=On'; \
|
||||
echo 'opcache.enable=1'; \
|
||||
echo 'opcache.validate_timestamps=0'; \
|
||||
} > /usr/local/etc/php/conf.d/zz-security.ini
|
||||
|
||||
WORKDIR /var/www/app
|
||||
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Установка зависимостей по зафиксированным версиям (мера ОПС.1, УКФ.1).
|
||||
COPY composer.json composer.lock ./
|
||||
RUN composer install --no-dev --no-interaction --no-progress --prefer-dist --no-scripts
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN composer dump-autoload --optimize \
|
||||
# Веб-сервер не должен иметь прав записи вне storage и bootstrap/cache (ЗИС).
|
||||
&& chown -R www-data:www-data storage bootstrap/cache \
|
||||
&& chmod -R 775 storage bootstrap/cache
|
||||
|
||||
USER www-data
|
||||
72
deploy/docker-compose.yml
Normal file
72
deploy/docker-compose.yml
Normal file
@@ -0,0 +1,72 @@
|
||||
# ============================================================================
|
||||
# Пример docker-compose для защищённого развёртывания (УЗ-1 / К1)
|
||||
# Сегментация (раздел 10 гайда): веб в одной сети, БД/Redis — во внутренней
|
||||
# сети без доступа из интернета (мера ЗИС.1).
|
||||
# Это ОБРАЗЕЦ для стенда; в проде используйте управляемые БД и секрет-хранилище.
|
||||
# ============================================================================
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: deploy/Dockerfile
|
||||
restart: unless-stopped
|
||||
env_file: ../.env
|
||||
depends_on:
|
||||
- pgsql
|
||||
- pgsql-audit
|
||||
- redis
|
||||
networks: [frontend, backend]
|
||||
volumes:
|
||||
- app-storage:/var/www/app/storage
|
||||
|
||||
nginx:
|
||||
image: nginx:1.27-alpine
|
||||
restart: unless-stopped
|
||||
depends_on: [app]
|
||||
ports:
|
||||
- "443:443"
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./nginx/app.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
- ./certs:/etc/ssl/app:ro
|
||||
networks: [frontend]
|
||||
|
||||
# Основная БД с ПДн — только во внутренней сети (ЗИС.1).
|
||||
pgsql:
|
||||
image: postgres:17-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${DB_DATABASE}
|
||||
POSTGRES_USER: ${DB_USERNAME}
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- pgsql-data:/var/lib/postgresql/data
|
||||
networks: [backend]
|
||||
|
||||
# Отдельная БД журнала аудита (РСБ.3) — изолированный экземпляр.
|
||||
pgsql-audit:
|
||||
image: postgres:17-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: ${AUDIT_DB_DATABASE}
|
||||
POSTGRES_USER: ${AUDIT_DB_USERNAME}
|
||||
POSTGRES_PASSWORD: ${AUDIT_DB_PASSWORD}
|
||||
volumes:
|
||||
- pgsql-audit-data:/var/lib/postgresql/data
|
||||
networks: [backend]
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
restart: unless-stopped
|
||||
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
|
||||
networks: [backend]
|
||||
|
||||
networks:
|
||||
frontend:
|
||||
backend:
|
||||
internal: true # Нет доступа в интернет из сегмента БД (ЗИС.1).
|
||||
|
||||
volumes:
|
||||
app-storage:
|
||||
pgsql-data:
|
||||
pgsql-audit-data:
|
||||
24
deploy/fail2ban/laravel-auth.conf
Normal file
24
deploy/fail2ban/laravel-auth.conf
Normal file
@@ -0,0 +1,24 @@
|
||||
# ============================================================================
|
||||
# fail2ban: блокировка перебора входа на уровне сети (мера ИАФ.6, ЗИС.2)
|
||||
# Дополняет блокировку учётной записи в приложении блокировкой IP.
|
||||
#
|
||||
# Установка:
|
||||
# 1) filter -> /etc/fail2ban/filter.d/laravel-auth.conf (секция [Definition])
|
||||
# 2) jail -> /etc/fail2ban/jail.d/laravel-auth.conf (секция [laravel-auth])
|
||||
# ============================================================================
|
||||
|
||||
[Definition]
|
||||
# Срабатывает на записи о неудачном входе в логах приложения/nginx.
|
||||
# Настройте под формат вашего лога (RSB: auth.login.failed).
|
||||
failregex = ^.*"event_type":"auth\.login\.failed".*"ip":"<HOST>".*$
|
||||
^<HOST> .* "POST /login HTTP.*" 4(0[39]|22|29) .*$
|
||||
ignoreregex =
|
||||
|
||||
[laravel-auth]
|
||||
enabled = true
|
||||
port = http,https
|
||||
logpath = /var/www/app/storage/logs/laravel.log
|
||||
/var/log/nginx/access.log
|
||||
maxretry = 5
|
||||
findtime = 600
|
||||
bantime = 1800
|
||||
67
deploy/nginx/app.conf
Normal file
67
deploy/nginx/app.conf
Normal file
@@ -0,0 +1,67 @@
|
||||
# ============================================================================
|
||||
# Пример конфигурации Nginx для защищённого Laravel-приложения (УЗ-1 / К1)
|
||||
# Меры ФСТЭК: ЗИС.9 (TLS), ЗИС (заголовки), ЗИС.2 (защита периметра).
|
||||
# Подставьте домен, пути к сертификатам и при необходимости — ГОСТ TLS.
|
||||
# ============================================================================
|
||||
|
||||
# Ограничение частоты запросов к форме входа (защита от перебора, ИАФ.6).
|
||||
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name example.local;
|
||||
# Принудительный редирект на HTTPS (ЗИС.9).
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
http2 on;
|
||||
server_name example.local;
|
||||
|
||||
root /var/www/app/public;
|
||||
index index.php;
|
||||
|
||||
# ---- TLS (ЗИС.9). Только TLS 1.2/1.3 ----------------------------------
|
||||
ssl_certificate /etc/ssl/app/fullchain.pem;
|
||||
ssl_certificate_key /etc/ssl/app/privkey.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off;
|
||||
|
||||
# Для государственных ИС: ГОСТ TLS через КриптоПро (ЗИС.16) — модуль
|
||||
# nginx с поддержкой ГОСТ-шифронаборов либо stunnel/КриптоПро.
|
||||
|
||||
# ---- Заголовки безопасности (дублируют middleware приложения) ---------
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
add_header X-Frame-Options "DENY" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
server_tokens off;
|
||||
|
||||
# ---- Ограничение размера загрузок (ЗИС, защита от исчерпания ресурсов) -
|
||||
client_max_body_size 10m;
|
||||
|
||||
location = /login {
|
||||
limit_req zone=login burst=5 nodelay;
|
||||
try_files $uri /index.php?$query_string;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
|
||||
fastcgi_hide_header X-Powered-By;
|
||||
}
|
||||
|
||||
# Запрет доступа к служебным и скрытым файлам.
|
||||
location ~ /\.(?!well-known).* { deny all; }
|
||||
location ~ /(storage|bootstrap|config|database|tests)/ { deny all; }
|
||||
}
|
||||
Reference in New Issue
Block a user