← Назад к вопросам

Как ограничить доступ к приватному репозиторию?

2.0 Middle🔥 122 комментариев
#Безопасность#Инфраструктура и DevOps

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Управление доступом к приватному репозиторию в PHP-проектах

Ограничение доступа к приватному репозиторию — критически важная задача для безопасности PHP-приложений. Вот комплексный подход к решению этой проблемы с практическими примерами.

1. Аутентификация и авторизация

JWT-токены — стандартный механизм для API. Пример реализации middleware в Laravel:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;

class JwtMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $token = $request->bearerToken();
        
        if (!$token) {
            return response()->json(['error' => 'Token required'], 401);
        }
        
        try {
            $decoded = JWT::decode($token, new Key(env('JWT_SECRET'), 'HS256'));
            $request->merge(['user' => $decoded->user]);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Invalid token'], 403);
        }
        
        return $next($request);
    }
}

2. Ролевая модель доступа (RBAC)

Реализация системы ролей и разрешений:

<?php

namespace App\Services;

class AuthorizationService
{
    private $userRoles;
    private $permissions = [
        'repository.read' => ['admin', 'developer'],
        'repository.write' => ['admin', 'lead_developer'],
        'repository.delete' => ['admin'],
        'repository.settings' => ['admin']
    ];
    
    public function hasAccess(string $permission, array $userRoles): bool
    {
        if (!isset($this->permissions[$permission])) {
            return false;
        }
        
        return !empty(array_intersect($userRoles, $this->permissions[$permission]));
    }
    
    public function checkRepositoryAccess($repositoryId, $userId): bool
    {
        // Проверка конкретных прав на репозиторий
        $access = DB::table('repository_access')
                   ->where('repository_id', $repositoryId)
                   ->where('user_id', $userId)
                   ->first();
        
        return $access !== null;
    }
}

3. IP-фильтрация и геолокация

Ограничение доступа по географическому признаку:

<?php

namespace App\Security;

class IPRestrictionService
{
    private $allowedIPs = ['192.168.1.0/24', '10.0.0.0/8'];
    private $blockedCountries = ['RU', 'CN', 'KP'];
    
    public function isAllowed($ip): bool
    {
        // Проверка по CIDR
        foreach ($this->allowedIPs as $cidr) {
            if ($this->ipInCidr($ip, $cidr)) {
                return true;
            }
        }
        
        // Проверка по стране
        $country = $this->getCountryByIP($ip);
        if (in_array($country, $this->blockedCountries)) {
            return false;
        }
        
        return false;
    }
    
    private function ipInCidr($ip, $cidr): bool
    {
        list($subnet, $mask) = explode('/', $cidr);
        return (ip2long($ip) & ~((1 << (32 - $mask)) - 1)) == ip2long($subnet);
    }
}

4. API Rate Limiting

Защита от брутфорса и DoS-атак:

<?php

namespace App\Security;

class RateLimiter
{
    private $limits = [
        'default' => ['attempts' => 100, 'window' => 3600],
        'repository_access' => ['attempts' => 10, 'window' => 300]
    ];
    
    public function check(string $key, string $type = 'default'): bool
    {
        $redis = new Redis();
        $redis->connect('127.0.0.1', 6379);
        
        $current = $redis->get("ratelimit:$type:$key");
        
        if ($current && $current >= $this->limits[$type]['attempts']) {
            return false;
        }
        
        $redis->multi();
        $redis->incr("ratelimit:$type:$key");
        $redis->expire("ratelimit:$type:$key", $this->limits[$type]['window']);
        $redis->exec();
        
        return true;
    }
}

5. Время работы и сессии

Ограничение времени доступа:

<?php

namespace App\Security;

class TimeRestriction
{
    public function isWorkingHours(): bool
    {
        $now = new DateTime('now', new DateTimeZone('Europe/Moscow'));
        $hour = (int)$now->format('H');
        $dayOfWeek = $now->format('N');
        
        // Только рабочие часы (9-18) в будни
        if ($dayOfWeek >= 6) return false;
        if ($hour < 9 || $hour >= 18) return false;
        
        return true;
    }
    
    public function checkSessionLifetime($sessionStart): bool
    {
        $maxSessionTime = 8 * 3600; // 8 часов
        return (time() - $sessionStart) < $maxSessionTime;
    }
}

6. Интеграция с внешними системами

Пример с LDAP/Active Directory:

<?php

class LdapAuth
{
    public function authenticate($username, $password)
    {
        $ldapConn = ldap_connect("ldap://domain.local");
        
        if (!$ldapConn) {
            throw new Exception("LDAP connection failed");
        }
        
        ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
        
        $ldapBind = @ldap_bind($ldapConn, "$username@domain.local", $password);
        
        if (!$ldapBind) {
            return false;
        }
        
        // Получение групп пользователя
        $search = ldap_search($ldapConn, "OU=Users,DC=domain,DC=local", 
                            "(samaccountname=$username)");
        $entries = ldap_get_entries($ldapConn, $search);
        
        return $this->extractUserGroups($entries[0]);
    }
}

Ключевые рекомендации:

  • Многоуровневая защита — комбинируйте несколько методов
  • Аудит и логирование — ведите детальные логи всех обращений
  • Регулярный пересмотр прав — периодически проверяйте актуальность доступов
  • Принцип минимальных привилегий — выдавайте только необходимые права
  • Шифрование данных — используйте HTTPS и шифрование чувствительных данных
  • Двухфакторная аутентификация — обязательна для административного доступа

Мониторинг и оповещения:

<?php

class SecurityMonitor
{
    public function logAccessAttempt($userId, $repositoryId, $success, $ip)
    {
        $logEntry = [
            'timestamp' => time(),
            'user_id' => $userId,
            'repository_id' => $repositoryId,
            'success' => $success,
            'ip' => $ip,
            'user_agent' => $_SERVER['HTTP_USER_AGENT']
        ];
        
        // Отправка в SIEM-систему
        $this->sendToSIEM($logEntry);
        
        // Оповещение при подозрительной активности
        if (!$success && $this->isSuspiciousPattern($logEntry)) {
            $this->sendAlert($logEntry);
        }
    }
}

Эти меры обеспечивают комплексную защиту приватных репозиториев, соответствуя лучшим практикам безопасности PHP-приложений. Важно регулярно обновлять и тестировать систему безопасности, адаптируя её к новым угрозам.