diff --git a/README b/README index b04df7c..7a1300e 100644 --- a/README +++ b/README @@ -43,35 +43,41 @@ Installation: 3. Apache setup: CentOS: - yum install httpd php php-mysqlnd mariadb-server + yum install httpd php php-mysqlnd php-redis redis mariadb-server cp configs/apache.conf.centos /etc/httpd/conf.d/text0nly.conf cp configs/php.ini /etc/php.ini chown -R apache:apache /var/www/html/main chmod -R 755 /var/www/html/main + systemctl start redis + systemctl enable redis systemctl start mariadb systemctl enable mariadb systemctl start httpd systemctl enable httpd Alpine: - apk add apache2 php php-mysql mariadb + apk add apache2 php php-mysql php-redis redis mariadb cp configs/apache.conf.debian /etc/apache2/sites-available/text0nly.conf cp configs/php.ini /etc/php/php.ini chown -R www-data:www-data /var/www/html/main chmod -R 755 /var/www/html/main ln -s /etc/apache2/sites-available/text0nly.conf /etc/apache2/sites-enabled/ + rc-update add redis default rc-update add mariadb default rc-update add apache2 default + rc-service redis start rc-service mariadb start rc-service apache2 start Debian: - apt install apache2 php mariadb-server + apt install apache2 php php-mysql php-redis redis mariadb-server cp configs/apache.conf.debian /etc/apache2/sites-available/text0nly.conf cp configs/php.ini /etc/php/php.ini chown -R www-data:www-data /var/www/html/main chmod -R 755 /var/www/html/main a2ensite text0nly.conf + systemctl start redis + systemctl enable redis systemctl start mariadb systemctl enable mariadb systemctl start apache2 @@ -86,6 +92,7 @@ Files: main/config.php - Database configuration (create from config.php.example) main/create.sql - Initial database structure main/migrate.sql - Database migrations + main/RateLimiter.php - DoS protection main/index.php - Main page main/register.php - Registration main/api.php - Message API diff --git a/main/RateLimiter.php b/main/RateLimiter.php new file mode 100644 index 0000000..5dd489e --- /dev/null +++ b/main/RateLimiter.php @@ -0,0 +1,32 @@ +redis = new Redis(); + $this->redis->connect('127.0.0.1', 6379); + } + + public function isAllowed($ip) { + $key = "rate_limit:{$ip}"; + $current = $this->redis->get($key); + + if (!$current) { + $this->redis->setex($key, $this->timeWindow, 1); + return true; + } + + if ($current >= $this->maxRequests) { + return false; + } + + $this->redis->incr($key); + return true; + } + + public function __destruct() { + $this->redis->close(); + } +} \ No newline at end of file diff --git a/main/api.php b/main/api.php index cbe3134..b8dfb7c 100644 --- a/main/api.php +++ b/main/api.php @@ -7,6 +7,14 @@ header('Content-Security-Policy: default-src \'self\''); session_start(); +require_once 'RateLimiter.php'; +$limiter = new RateLimiter(); + +if (!$limiter->isAllowed($_SERVER['REMOTE_ADDR'])) { + http_response_code(429); + die(json_encode(['error' => 'Too many requests'])); +} + if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!isset($_SESSION['csrf_token']) || !isset($_SERVER['HTTP_X_CSRF_TOKEN']) || $_SESSION['csrf_token'] !== $_SERVER['HTTP_X_CSRF_TOKEN']) {