, ,

12 января, 2025

Обход защиты сайтов от парсинга данных или anti-anti-scraping

Допустим, есть задача написать парсер, который бы получал данные сайта и складывал их в локальную базу данных. На первый взгляд это очень простая и тривиальная задача, но при реализации оказывается, что многие сайты используют механизмы защиты от прямого парсинга. Такие защиты могут включать:

  • Формирование HTML-страницы с помощью JavaScript.
  • Ожидание специальных заголовков или куки.
  • Блокировку «подозрительных» запросов.

Посмотрев на это, я немного приуныл и начал искать способ быстрее решить задачу. Мне нужно было решение, которое бы запускало парсер так, как если бы запрос выполнял обычный браузерный пользователь. В голову сразу пришла идея использовать Chromium как сервис внутри Docker. Я мог бы передавать ссылку страницы в этот сервис, а в ответ получать HTML уже после отработки JavaScript.

Выбор инструментов

Парсить я планирую на PHP. В качестве браузерного сервиса я выбрал Selenium. Также можно использовать Puppeteer, но он у меня не запустился под Docker, поэтому я отказался от него.

Selenium — это инструмент для тестировщиков, позволяющий автоматизировать действия на сайте с помощью эмуляции браузера. Мне достаточно одного браузера — Chrome, но Selenium поддерживает и другие браузеры. Подробнее можно прочитать на официальном сайте: https://www.selenium.dev

version: '3.8'

services:

  selenium:
    image: selenium/hub:4.8.0  # Selenium Hub
    container_name: selenium_parser
    environment:
      - GRID_MAX_SESSION=5
      - GRID_BROWSER_TIMEOUT=300
      - GRID_TIMEOUT=300
    networks:
      - network

  chrome:
    image: selenium/node-chrome:4.8.0  # Браузер Chrome
    shm_size: 2gb
    depends_on:
      - selenium
    environment:
      - SE_EVENT_BUS_HOST=selenium
      - SE_EVENT_BUS_PUBLISH_PORT=4442
      - SE_EVENT_BUS_SUBSCRIBE_PORT=4443
    networks:
      - network

  php:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: parser_php
    volumes:
      - ./:/var/www/html
    depends_on:
      - selenium
    networks:
      - network

networks:
  network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.210.0/28

selenium — контейнер с нашим Selenium, который будет использоваться как сервис для запуска сайтов из браузера Chrome.

chrome — контейнер с браузером (можно добавить контейнеры с другими браузерами, если нужно).

php — контейнер с PHP-скриптом.

Поскольку я буду использовать стороннюю библиотеку Composer для взаимодействия с API Selenium, мне нужно, чтобы Composer был установлен в моем контейнере PHP. Для этого создаем дополнительный Dockerfile для PHP.

# Используем базовый образ PHP 8.3
FROM php:8.3-fpm

# Установка необходимых пакетов
RUN apt-get update && apt-get install -y \
    git \
    unzip \
    libpq-dev \
    && docker-php-ext-install bcmath

# Установка Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Установка Symfony CLI
RUN curl -sS https://get.symfony.com/cli/installer | bash \
    && mv /root/.symfony*/bin/symfony /usr/local/bin/symfony

# Установка прав доступа к директории
WORKDIR /var/www/html

Запуск Docker Compose

Теперь все готово для запуска docker-compose:

$ docker-compose up -f docker-compose.yaml

Обратите внимание, что я использую минимальный набор контейнеров. В реальном проекте для полноценного парсера потребуются контейнеры с HTTP-сервером, базой данных, Redis и т. д. Поскольку написание полноценного парсера выходит за рамки этого поста, здесь я привожу пример упрощенной конфигурации docker-compose.

Заходим в контейнер PHP и инициализируем Composer:

$ docker exec -it parser_php bash

docker# composer require php-webdriver/webdriver 

После успешной инициализации Docker пишем небольшой скрипт на PHP для проверки работоспособности Selenium:

<?php

require_once 'vendor/autoload.php';

use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\Remote\DesiredCapabilities;

// Подключение к Selenium Hub
$host = 'http://selenium:4444/wd/hub'; // URL Selenium Hub
$capabilities = DesiredCapabilities::chrome(); // Используем Chrome
$driver = RemoteWebDriver::create($host, $capabilities);

// Открываем страницу
$driver->get('https://example.com');

// Получаем HTML страницы
$html = $driver->getPageSource();
echo $html;

// Закрываем браузер
$driver->quit();

Все теперь можно из контейнера с php обращаться к любым сайтам через selenium как полноценный браузер Chrome, выполнять JS, можно эмулировать обычные действия пользователя на сайте, все зависит от вашей фантазии, задачи.

Теперь можно из контейнера PHP обращаться к любым сайтам через Selenium как полноценный браузер Chrome. Вы можете выполнять JavaScript, эмулировать действия пользователя на сайте — все зависит от ваших задач и фантазии.

, , ,

6 января, 2025

Разворачиваем git хранилище на своем сервере

Всем привет! Сегодня хочу рассказать про установку такого замечательного программного обеспечения как Gitea. Данный продукт предназначен для удобного доступа к git хранилищу, напоминает по своим возможностям gitlab, github, bitbucket.

Сейчас особенно полезно задуматься о создании своих независимых git хранилищ потому что пидарская протекционистская политика государств нарастает и очень вероятно, что в будущем пользователей из России могут лишить доступа к github или bitbucket, а код где-то хранить необходимо и так как мудаки гениальные стратеги отвечающие за импортузамещение до сих пор не создали ничего более менее альтернативного в России, то лучше создавать свои хранилища на своих выделенных серверах. Gitea прекрасно подходит в качестве альтернативы, а так же он гораздо проще в установке и настройке чем тот же самый GitLab.

Для установки я выбрал способ развертывания через docker compose, так что требуется установить docker если это еще не сделано, затем создать директорию в котором будет находится файловая система gitea и создать файл docker-compose.yaml

$ sudo apt update
$ sudo apt install -y docker.io
$ sudo systemctl start docker
$ sudo systemctl enable docker
$ sudo apt install -y docker-compose
$ mkdir ~/gitea && cd ~/gitea
$ vim docker-compose.yml

Соответственно, на хостинге у меня Ubuntu ( если у вас что-то другое, используйте свои команды для установки Docker ). В качестве редактора само собой я использую православный vim

version: '3.7'

services:
  db:
    image: postgres:15
    container_name: gitea-db
    environment:
      POSTGRES_USER: gitea
      POSTGRES_PASSWORD: gitea_password
      POSTGRES_DB: gitea
    volumes:
      - ./db:/var/lib/postgresql/data
    restart: always

  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    volumes:
      - ./gitea:/data
    ports:
      - "127.0.0.1:3000:3000" # Веб-интерфейс Gitea
      - "2222:22"   # SSH для клонирования репозиториев
    depends_on:
      - db
    restart: always

В качестве базы данных я решил использовать postgres. Поменяйте доступы к базе данных. В принципе gitea поддерживает разные СУБД, можете использовать свой любимый. Описание портов есть в комментариях.

Так как мне нужен был отдельный домен для git я указал проброс порта 3000 только для 127.0.0.1 поэтому из вне к нему нельзя обратится ( далее я покажу как разрулить порт через настройку nginx )

Теперь создаем любымый Makefile для удобства

.PHONY: up down restart logs ps clean help

# Переменные
COMPOSE_FILE = docker-compose.yml
PROJECT_NAME = gitea_project

# Команды
up: ## Запускает все контейнеры в фоне
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) up -d

down: ## Останавливает контейнеры и освобождает ресурсы
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down

restart: ## Перезапускает все контейнеры
	$(MAKE) down
	$(MAKE) up

logs: ## Показывает логи контейнеров в реальном времени
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) logs -f

ps: ## Отображает состояние запущенных контейнеров
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) ps

clean: ## Удаляет все контейнеры, тома и связанные ресурсы
	docker-compose -p $(PROJECT_NAME) -f $(COMPOSE_FILE) down --volumes --remove-orphans

help: ## Показывает это сообщение
	@echo "Доступные команды:"
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "  %-15s %s\n", $$1, $$2}'

.DEFAULT_GOAL := help

В Makefile можно вынести необходимые команды для работы с докером

В процессе запуска у меня возникли некоторые сложности при запуске докера на хостинге поэтому пришлось установить питон

$ sudo apt update 
$ sudo apt install python3 -y
$ sudo apt install python3-pip -y

Запускать docker-compose up от рута плохая идея поэтому необходимо добавить пользователя в группу docker и запускать docker-compose от обычного пользователя, для этого добавляем пользователя <your-user> в группу docker

$ sudo usermod -a -G docker <your-user>

Ну или так:

$ sudo usermod -aG docker $USER

После добавления пользователя в группу требуется перезапустить shell ( без этого make up ругался на то что у пользователя не хватает прав )

Теперь требуется привязать домен к нашему локальному порту 3000 на котором запущен gitea, для этого нужно перейти к настройкам nginx и создать конфиг для сервиса gittea

$ cd /etc/nginx/sites-available
$ vim gitea

Добавляем подобное содержимое

server {
        server_name domain.ru www.domain.ru;
        location / {
                proxy_pass http://localhost:3000;
        }
}

Тут все понятно — все внешние запросы проксируются на локальный порт 3000 на котором запущен наш gitea

Далее создаем линк на /etc/nginx/sites-available/gitea в
/etc/nginx/sites-enabled и перезапускаем nginx

$ sudo ln -s /etc/nginx/sites-enabled/gitea /etc/nginx/sites-available/gitea
$ sudo nginx reload

После этого я рекомендую так же настроить SSL сертификаты для нашего хранилища, я использую для этой цели certbot

$ cerbot --nginx -d domain.ru -d www.domain.ru

Чуть не забыл важный момент, необходимо создать службу в Ubuntu, которая позволит автоматически поднимать docker-compose с gitea при перезагрузки сервера, для этого создаем новую пользовательскую службу systemd

$ cd /etc/systemd/system/
$ sudo vim gitea.service

Добавляем код нового сервиса в gitea.service

[Unit]
Discription=Gitea
After=docker.service
Requires=docker.service

[Service]
WorkerDirectory=/var/www/gitea/
ExecStart=docker-compose -p gitea_project -f /var/www/gitea/docker-compose.yml up
ExecStartPost=service nginx reload
ExecStop=docker-compose -p gitea_project -f /var/www/gitea/docker-compose.yml down
Restart=on-failure

[Install]
WantedBy=multi-user.target

Тут особо пояснять нечего. Указываем, что служба запускается только после запуска docker.service и для нее обязательно должен быть запущен docker.service

Запускаем

$ sudo systemctl daemon-reload
$ sudo systemctl enable gitea

Все! На этом настройки сервера закончены и можно приступать к установке gitea.

Открываем браузер и переходим на страницу domain.ru ( тот домен который мы указали в настройках nginx )

Откроется окно со множеством настроек, я не буду приводить все настройки, остановлюсь только на настройках базы данных и админского доступа.

Тут необходимо заполнить настройки данными, которые были указаны в docker-compose.yml

POSTGRES_USER: gitea
POSTGRES_PASSWORD: gitea_password
POSTGRES_DB: gitea

Собственно имя пользователя базы данных, имя базы данных и ваш пароль. В качестве СУБД выбираем postgreSQL

Так же можно сразу же настроить тут порт для ssh соединения, в нашем случае это будет порт 2222

И настроить доступы для администратора Gitea:

После этого нажимаем на кнопку Устанивать Gitea. Ждем пока система установится и можно приступать к работе с Gitea. Интерфейс системы интуитивно понятен, а по функционалу не сильно отличается от привычного Gitlab. Работает достаточно шустро.

На что стоит обратить внимание, конечно настройки базы данных лучше вынести в .env файл из docker-compose.yml а так же может еще имеет смысл настроить работу своего git хранилища внутри вашего собственного VPN, но это уже немного выходит за рамки темы статьи.

На этом все, если будут вопросы пишите в мне в телеграм и обязательно подписывайтесь на канал в телеграме в которой публикуются новинки на сайте.

, , ,

15 декабря, 2024

Поднимаем Chat GPT у себя на компьютере

Привет! Сегодня хотел бы рассказать как можно развернуть на своей локальной машине аналог чата GPT. Особых знаний для этого иметь не нужно. Все достаточно просто.

Для тех кто не знает что такое chatGTP, то это  чат-бот с генеративным искусственным интеллектом, разработанный компанией OpenAI и способный работать в диалоговом режиме, поддерживающий запросы на естественных языках. ( кусок из Викепедии )

Но возможно не все знают, что существуют альтернативные чат боты, платные и бесплатные, централизованные и децентрализованные

Существует несколько популярных моделей с открытым исходным кодом, которые можно развернуть локально:

Эти модели предоставляют функциональность, схожую с ChatGPT, но менее мощные.

Так же существуют децентрализованные аналоги чата GPT но тут я не буду об этом писать, хотя тема децентрализации подобных систем мне кажется достаточно интересной.

По-своей сути подобные чаты представляют из себя ML-модели

ML (Machine Learning) — это технология, позволяющая компьютерам обучаться и принимать решения на основе данных, не будучи явно запрограммированными. ML-модель — это математическое представление данных и логики, которое позволяет системе делать предсказания или выполнять задачи, анализируя входные данные.

Основные этапы работы ML-модели:

  1. Сбор данных: Системе нужны данные для обучения.
  2. Обработка данных: Данные очищаются, нормализуются и подготавливаются для анализа.
  3. Обучение: Модель обучается на данных, выявляя закономерности и зависимости.
  4. Валидация: Проверяется, как хорошо модель работает на новых данных.
  5. Применение: Обученная модель используется для анализа новых данных.

Типы ML-моделей:

  1. Супервизорное обучение (Supervised Learning): Обучение на размеченных данных (например, классификация писем как «спам» или «не спам»).
  2. Без учителя (Unsupervised Learning): Выявление скрытых структур в неразмеченных данных (например, кластеризация клиентов).
  3. Обучение с подкреплением (Reinforcement Learning): Модель учится через награды за правильные действия (например, обучение робота).

Для чего это вообще может пригодится в быту? Да для чего угодно :) На базе генеративного чата ИИ вы можете создать своего персонального помощника, который сможет предоставлять вам те данные, которые вам необходим, например, в работе. При этом он будет работать автономно на вашем компьютере и абсолютно бесплатно, так он вполне работает без подключения к интернету.

В данной статье я бы хотел продемонстрировать как достаточно просто можно развернуть чат ollana, пару слов о том, что из себя представляет ollama

Ollama — это платформа и инструмент для локальной работы с большими языковыми моделями (LLM, Large Language Models). Она позволяет запускать и использовать LLM прямо на вашем устройстве, не требуя обращения к внешним серверам.

Основные особенности Ollama:

  • Локальная работа: Запуск моделей происходит локально, что повышает конфиденциальность и безопасность.
  • Оптимизация: Использует аппаратные ресурсы устройства максимально эффективно.
  • Поддержка популярных моделей: Ollama работает с различными открытыми и специализированными языковыми моделями, включая модели вроде Llama 2, Alpaca, или GPT.

Модели: Ollama предоставляет доступ к языковым моделям, которые работают с текстами. Это может быть генерация текста, обработка запросов, написание кода и многое другое.

Технология:

  • Использует LLM, которые обучены на огромных текстовых датасетах.
  • Поддерживает работу с моделями, оптимизированными для локального запуска.
  • Совместима с архитектурами, такими как Transformer, лежащими в основе современных LLM.

Применение:

  • Генерация текста (автоматизация переписки, написание статей).
  • Классификация (определение тематики текста).
  • Анализ (суммаризация текста, ответ на вопросы).

Ollama может использовать любые модели, доступные в формате GGML, подходящем для локального запуска.

По управлению ollama немного напоминает docker

Для установки ollama нужно перейти на официальный сайт и скачать версию для вашей операционной системы

После установке можно запустить ollama выполнив команду в консоле:

$ ollama run llama3.2

Данная команда скачает и запустит модель llama3.2

Список моделей доступных для ollama можно посмотреть тут модели могут быть мощными 90B и выше, так и менее мощными 2B

Можно установить любое количество моделей ( если у вас хватает ресурсов ), для просмотра уже скаченных моделей можно воспользоваться командой:

$ ollama list

NAME               ID              SIZE      MODIFIED     
codestral:22b      0898a8b286d5    12 GB     12 hours ago    
phi:latest         e2fd6321a5fe    1.6 GB    14 hours ago    
llama3.2:latest    a80c4f17acd5    2.0 GB    4 days ago 

Так же хотелось бы отметить, что такое 2B, 90B. Это обозначения, которые указывают на количество параметров в машинной модели (в миллиардах, где B означает billion — миллиард). Параметры — это числовые значения, которые модель настраивает во время обучения для выполнения задач, таких как обработка текста или генерация ответов. К примеру, GPT-4 использует 1.8 триллиона параметров (или 1,800 миллиардов)

Большие и мощные модели потребуют больших ресурсов компьютера для работы. Они потребляют больше процессорной мощности, памяти и занимают достаточно большой объем жесткого диска.

И так, после выполнения команды, мы уже сможем работать с чатом из командной строки.

так же после запуска чат доступен по адресу http://localhost:11434, по которому можно обратится, сформировав HTTP запрос. Вот пример как это сделать:

На curl из командной строки:

curl -X POST http://localhost:11434/api/generate \
-H "Content-Type: application/json" \
-d '{
  "model": "llama3.2",
  "prompt": "Привет! Как дела?",
  "stream": false
}'

Получаем ответ, что-то вроде:

{
  "model": "llama3.2",
  "created_at": "2024-12-14T22:15:02.891574Z",
  "response": "Здравствуйте! Я работаю нормально, gracias за вопрос. Как youre?",
  "done": true,
  "done_reason": "stop",
  "context": [
    ...
  ],
  "total_duration": 1162500333,
  "load_duration": 50502583,
  "prompt_eval_count": 32,
  "prompt_eval_duration": 618000000,
  "eval_count": 20,
  "eval_duration": 491000000
}

Тут важно отметить, что если не передать в теле запроса «stream»: false то ответ будет возвращаться в виде так называемых чанков, на каждое генерацию ответа:

{"model":"llama3.2","created_at":"2024-12-14T22:12:32.01656Z","response":"Пр","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.032929Z","response":"ив","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.054271Z","response":"ет","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.076969Z","response":"!","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.098469Z","response":" Как","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.122245Z","response":" я","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.144477Z","response":" могу","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.165088Z","response":" пом","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.186886Z","response":"очь","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.207423Z","response":" вам","done":false}
{"model":"llama3.2","created_at":"2024-12-14T22:12:32.229528Z","response":"?","done":false}
...

Так же к чату можно обращаться из своих скриптов, вот простой пример скрипта на PHP:

<?php

$url = 'http://localhost:11434/api/generate';
$data = [
    "model" => "llama3.2",
    "prompt" => "Привет! Как дела?",
    "stream" => true // включение потокового режима
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_WRITEFUNCTION, function($curl, $chunk) {
    // Обрабатываем чанки текста
    $response = json_decode($chunk, true);
    if (isset($response['response'])) {
        echo $response['response'];
    }
    return strlen($chunk);
});

curl_exec($ch);
curl_close($ch);

Далее не помешало бы настроить какой-то удобный интерфейс для взаимодействия с ИИ чатом. Для этого можно воспользоваться готовым решением — open-webui

Open-webui — это графический интерфейс при помощи которого можно подключаться как к локальным так и к удаленным генеративным моделя наподобие chatGPT или LLaMa

open-webui можно установить локально ( для этого потребуется установить Paython ) или воспользоваться образом из докера. Мне больше нравится работать с докером, поэтому я выбрал вариант с контейнером:

$ docker run -d -p 3000:8080 -e OLLAMA_BASE_URL=http://host.docker.internal:11434 -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main

Тут важно отметить, что я указал в команде значение переменной -e OLLAMA_BASE_URL=http://host.docker.internal:11434

Она указывает на адрес на котором ollama запускается локально. В моем случае подобный вариант запуска привел к тому, что UI web интерфейса очень сильно тормозил, поэтому в команде я указал вместо http://host.docker.internal:11434 — http://localhost:11434 а уже после запуска изменил адрес на http://host.docker.internal:11434 из панеле управления: Админ Панель -> настройки -> соедниение

После запуска, open-webui будет доступен по адресу http://localhost:3000

Нужно будет зарегистрироваться и можно общаться с чатом:

Ну вот и все! Надеюсь данная информация будет полезна кому-нибудь.

, ,

5 декабря, 2024

Netcat: универсальный швейцарский нож для сетевых операций

Давно на этом сайте не было статей про unix way подход. Не было ничего насчет инструментов командной строки, который нельзя игнорировать даже в наш век сложных UI UX инструментов, командная строка остается один из самых эффективных инструментов в профессиях связанных с IT индустрией, поэтому тут хотел бы рассказать и привести примеры взаимодействия с сетью через такую замечательную команду как netcat доступная в большинстве дестрибутивом unix подобных систем

Итак, поехали!

Netcat (nc) — это маленькая, но мощная утилита в мире UNIX, которая часто упоминается как «швейцарский нож» для сетевых операций. Она позволяет нам отправлять и принимать данные по сети, а также может заменить сразу несколько специализированных утилит. В этой статье мы разберём, как nc может облегчить жизнь системного администратора, разработчика, а также просто энтузиаста, заинтересованного в исследовании сетевых возможностей.

Зачем нужен Netcat?

Использование nc может быть полезно для диагностики сети, передачи файлов, отладки сетевых приложений и даже создания простых серверов и клиентов. Главный плюс — это гибкость nc и поддержка широкого диапазона сетевых протоколов и операций.

Установка Netcat

В большинстве UNIX-систем Netcat уже установлен. Но если вдруг у вас его нет, можно легко добавить его через менеджер пакетов:

# На Debian/Ubuntu
sudo apt install netcat

# На CentOS/RHEL
sudo yum install nc

# На MacOS
brew install netcat

Теперь, когда nc у нас на борту, давайте разберёмся с реальными примерами использования.

1. Диагностика открытых портов

Вы хотите узнать, открыт ли определённый порт на сервере, или, возможно, провести быструю диагностику состояния сети? Netcat может помочь!

nc -zv example.com 80
  • -z — режим проверки портов (без отправки данных).
  • -v — включение режима подробного вывода (verbose).

Пример вывода:

Connection to example.com 80 port [tcp/http] succeeded!

Этот трюк полезен для быстрого анализа открытых портов на сервере, например, при проверке, работает ли сервер после перезагрузки.

2. Передача файлов

Netcat можно использовать для передачи файлов по сети — простой и быстрый способ отправить что-то, не прибегая к сложным утилитам.

На стороне отправителя (отправка файла):

cat myfile.txt | nc -l 1234

На стороне получателя (приём файла):

nc <IP-адрес> 1234 > receivedfile.txt

После выполнения этих команд содержимое myfile.txt на отправляющей стороне будет передано и сохранено как receivedfile.txt на принимающей стороне. Эта опция отлично подходит для работы в рамках одного сегмента сети или виртуальной среды.

3. Запуск простого сервера или тестового чата

Допустим, вы хотите создать простой сервер для прослушивания на определённом порту, чтобы принимать текстовые сообщения или проверять сетевые соединения. Netcat справится с этим в два счёта!

# Серверная сторона
nc -l 5555

Сервер готов и прослушивает подключение на порту 5555. Теперь на клиентской стороне подключаемся к этому порту:

# Клиентская сторона
nc <IP-адрес сервера> 5555

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

4. Реализация теста скорости сети

С помощью nc и pv (pipe viewer) можно провести тест скорости сети, чтобы понять, насколько хорошо она работает. В этом случае pv отправляет данные через nc, и это полезно, когда требуется быстро протестировать локальную сеть.

На серверной стороне:

nc -l 5555 > /dev/null

На клиентской стороне:

pv /dev/zero | nc <IP-адрес сервера> 5555

Такой тест позволяет вам видеть скорость передачи данных в режиме реального времени, что может быть полезно для диагностики проблем с сетью.

5. Проверка DNS-серверов и отправка DNS-запросов

С помощью nc можно отправить DNS-запрос напрямую на сервер для отладки или диагностики.

Например, чтобы отправить DNS-запрос на определённый сервер, можно использовать комбинацию с echo:

echo -e "\x12\x34\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01" | nc -u 8.8.8.8 53
  • Команда echo -e создаёт DNS-запрос в шестнадцатеричном формате, чтобы запросить www.google.com.
  • -u указывает, что нужно использовать UDP, так как DNS работает на этом протоколе.

Это полезно для диагностики сетевых проблем и проверки того, как работает DNS-сервер.

6. Мониторинг TCP и UDP портов (сетевой сниффер)

Netcat может быть использован как базовый сетевой сниффер для мониторинга входящих данных на портах. Например, если нужно прослушивать UDP-порт на 5555:

nc -u -l 5555

Этот режим полезен для диагностики UDP-соединений или проверки активности на порту, особенно если данные передаются по сети случайным образом.

7. Проверка доступности веб-сайта и получение HTTP-заголовков

С помощью nc можно проверить, правильно ли работает веб-сервер, отправив к нему HTTP-запрос и получив заголовки ответа.

echo -e "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 80

Этот запрос отправляет простую команду GET на сервер example.com, и Netcat возвращает HTTP-заголовки, позволяя увидеть статус-сообщение и понять, отвечает ли сервер.

8. Создание резервной копии диска через сеть

Netcat можно использовать для копирования содержимого одного жесткого диска на другой через сеть. Этот метод подойдёт для создания резервных копий или клонирования.

На стороне отправителя:

dd if=/dev/sda | nc -l 1234

На стороне получателя:

nc <IP-адрес отправителя> 1234 | dd of=/dev/sdb

Здесь dd используется для чтения данных с диска, а nc передаёт эти данные по сети на другой диск. Это эффективный способ, но требует осторожности, так как данные могут быть перезаписаны.

9. Отправка сообщений в чат в несколько потоков

Netcat можно настроить для создания текстового чата между несколькими пользователями, что пригодится, например, для координации действий в одной сети.

На стороне сервера:

mkfifo mypipe
nc -l 1234 < mypipe | tee mypipe

На стороне клиента:

nc <IP-адрес сервера> 1234

Тут мы используем именованный канал (FIFO) mypipe для передачи данных в двух направлениях. Это позволяет передавать сообщения от всех подключённых клиентов серверу и обратно.

10. Сканирование диапазона портов на удалённом сервере

Netcat может быть использован для быстрого сканирования диапазона портов, чтобы узнать, какие из них открыты. Хотя это и не заменяет полноценные сканеры (как nmap), Netcat предоставляет простое решение.

for port in {20..25}; do
  echo "" | nc -v -w 1 -z example.com $port
done
  • -w 1 устанавливает таймаут в 1 секунду.
  • -z указывает на то, что нам нужно только проверить открытость порта, не отправляя данных.

Это полезно для быстрого анализа доступных портов на целевом сервере.

11. Организация обратного подключения для удалённого доступа

Для отладки или диагностики можно организовать обратное подключение с использованием nc, чтобы получить доступ к удалённой системе.

На целевой стороне:

nc -l -p 1234 -e /bin/bash

На управляющей стороне:

nc <IP-адрес целевой машины> 1234

После подключения управляющая сторона сможет получить доступ к командной строке удалённого сервера. Однако важно помнить, что этот метод небезопасен и должен использоваться только в закрытых и безопасных средах.

12. Перехват и просмотр трафика на локальном интерфейсе

Перехват и просмотр трафика на локальном интерфейсе

Если вы хотите быстро посмотреть, что за трафик проходит через ваш локальный интерфейс, можно использовать комбинацию nc и tcpdump.

tcpdump -i eth0 -s0 -w - | nc -l 1234

Эта команда захватывает трафик на интерфейсе eth0 и передаёт его через nc для анализа. На другой стороне можно подключиться к этому порту и просматривать трафик в реальном времени.

Ну и немного совсем экзотических примеров использования команды nc

13. Создание простого веб-сервера на базе nc

С помощью nc можно запустить минималистичный HTTP-сервер на своём компьютере, который будет отдавать статический файл или HTML-страницу. Это может пригодиться для быстрой демонстрации или тестирования локально без полноценного веб-сервера.

Пример команды для одностраничного веб-сервера:

while true; do echo -e "HTTP/1.1 200 OK\r\nContent-Length: $(wc -c < index.html)\r\n\r\n$(cat index.html)" | nc -l -p 8080; done
  • Эта команда запускает бесконечный цикл, который отдаёт содержимое файла index.html по HTTP на порт 8080.
  • Подойдёт для тестов, проверки HTTP-запросов и небольших демонстраций.

Теперь, зайдя на http://localhost:8080 в браузере, можно увидеть содержимое index.html.

14. Туннелирование TCP-порта через UDP (обход блокировок)

Когда на брандмауэре разрешены только UDP-порты, nc можно использовать для проброса TCP-трафика через UDP, обходя тем самым блокировки на уровне сети. Это немного хакерский метод, но работает в специфичных случаях.

Серверная сторона (UDP к TCP-туннель):

nc -u -l -p 5555 | nc localhost 80

Здесь nc принимает UDP-пакеты на порту 5555 и перенаправляет их к TCP-соединению на локальный порт 80 (обычно HTTP).

Клиентская сторона:

echo "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" | nc -u <IP-адрес сервера> 5555

Таким образом можно протестировать HTTP через UDP, например, когда нужно обойти некоторые ограничения сетевых правил.

15. Переключатель музыки или медиа-сервера через аудиопоток

С помощью nc можно создать простое потоковое аудио- или видеовещание. Например, для проигрывания музыки на другой машине по сети.

На стороне отправителя:

cat song.mp3 | nc -l -p 4000

На стороне получателя:

nc <IP-адрес отправителя> 4000 | mpv -
  • Эта команда передаёт файл song.mp3 через nc, а на принимающей стороне поток воспроизводится плеером mpv.
  • Подходит для потоковой передачи аудиофайлов или даже видео через локальную сеть без сложной настройки.

16. Координация команд в кластере

Если у вас есть несколько серверов, и вам нужно выполнить одну и ту же команду на каждом из них, nc можно использовать для координации. Один сервер действует как мастер, отправляя команды всем остальным.

На сервере-мастере:

echo "ls -l /home" | nc -w 1 <IP-адрес сервера1> 1234
echo "ls -l /home" | nc -w 1 <IP-адрес сервера2> 1234

На каждом из серверов:

nc -l 1234 | bash
  • Эта команда отправляет ls -l /home от мастера, и все серверы её выполняют.
  • Применимо для быстрой автоматизации команд или тестирования на нескольких серверах без сложной настройки.

17. Секретное сообщение с самоуничтожением

Можно отправить сообщение через nc с таймером самоуничтожения, чтобы оно удалилось сразу после прочтения, как в шпионских фильмах.

На стороне отправителя:

echo "Это сообщение самоуничтожится через 5 секунд" | nc -l -p 5000

На стороне получателя:

nc <IP-адрес отправителя> 5000 && sleep 5 && echo "Сообщение удалено"

После того как сообщение прочитано, команда sleep 5 завершает выполнение через 5 секунд, и на экране выводится сообщение о том, что оно было «удалено».

На этом пока что все. Буду время от времени еще выкладывать интересные инструменты командный строки.

, , ,

7 ноября, 2024

Устанавливаем Shadowsocks на свой сервер

Для начала стоит объяснить, что такое Shadowsocks и для чего он может быть полезен.

Иногда вы можете оказаться в сети с ограничениями, где фильтруется интернет-трафик, и доступ к определённым ресурсам блокируется. Такие ограничения могут встречаться, например, в корпоративной сети на работе. Если вам необходимо обойти такие блокировки и получить доступ к нужным сайтам, на помощь может прийти инструмент под названием Shadowsocks. По сути, это прокси-сервер, который использует протокол SOCKS5 для передачи данных.

Протокол SOCKS5 позволяет создать зашифрованное соединение и направлять трафик через него, делая его менее заметным для фильтров и блокировок. В этой статье я расскажу, как быстро развернуть свой прокси-сервер с использованием Shadowsocks. Чем-то это напоминает создание шифрованного тоннеля через ssh.

Для начала вам необходим свой сервер. Если у вас еще нет своего сервера, то переходите по ссылке и зарегистрируйте его. Хостинг дает сутки на тестирование, поэтому можно проверить как работает тот же sadownsocks, например.

После того как у вас появился свой сервер, необходимо установить shadowsocks
это легко сделать при помощи нескольких команд:

$ sudo apt update
$ sudo apt install shadowsocks-libev

Теперь нужно создать основной файл с настройками shadowsocks. Поэтому создаем в /etc/shadowsocks-libev файл config.json со следующем содержимым:

{
    "server": "[server]",
    "server_port": "[server_port]",
    "password":"[password]",
    "mode":"tcp_and_udp",
    "timeout": 300,
    "local_port": "[local_port]",
    "method": "xchacha20-ietf-poly1305",
    "fast_open": true,
    "nameserver": "8.8.8.8"
}

server — ip адрес сервера
server_port — сервер порт через который будет создан тоннель ( замените на свой )
password — пароль подключения ( замените на свой )
method — метод шифрования ( если не уверены, то лучше оставить такой как в примере )
local_port — порт на локальной машине через который будет проходить зашифрованный трафик

Если у вас на сервере установлен файрвол, то необходимо открыть порт, который был указан в настройках:

$ sudo ufw allow [server_port]
$ sudo ufw reload

Теперь можно запустить shadowsocks:

$ sudo systemctl restart shadowsocks-libev

После этого на сервере все готово и можно приступать к настройке клиентской части.

Для того, чтобы запустить зашифрованный socks5 на вашей локальной машине потребуется установить Shadowsocks клиент. Вот несколько вариантов для разных систем:

Windows

  1. Shadowsocks for Windows — Официальный клиент с графическим интерфейсом.
  2. ShadowsocksR — Модифицированная версия Shadowsocks, поддерживающая дополнительные шифрования и функции.
  3. Outline — Простой в использовании клиент, который также поддерживает Shadowsocks и удобен для новичков.

macOS

  1. ShadowsocksX-NG — Популярный клиент для macOS с поддержкой Shadowsocks и дополнительными функциями.
  2. Outline — Также доступен для macOS, позволяет легко подключаться к Shadowsocks-серверам.

Linux

  1. Shadowsocks-libev — Лёгкий клиент для Linux, поддерживающий командную строку и простой в настройке.
  2. Outline — Клиент с графическим интерфейсом, доступный для нескольких версий Linux.
  3. Shadowsocks-qt5 — Версия с графическим интерфейсом, подходящая для пользователей, предпочитающих GUI.

Android

  1. Shadowsocks for Android — Официальное приложение для Android с поддержкой настроек и переключений.
  2. ShadowsocksR Android — Вариант с дополнительными настройками и функциями.
  3. Outline — Отличный вариант для пользователей, которые хотят быстро подключиться без сложных настроек.

iOS

Outline — Простое и удобное приложение, особенно для начинающих.

Shadowrocket — Один из самых популярных и мощных клиентов для iOS, поддерживает Shadowsocks и другие протоколы.

Potatso Lite — Поддерживает Shadowsocks и имеет удобный интерфейс.

Выбираем подходащий клиент и настраиваем соединение в нем для сервера на который поставили shadwonsocks

После установки соединения SOCKS5 будет доступен на локальной машине на порту local_port который ранее мы указали в настройках shadownsock на сервере

Ну вот и все. Следите за обновлениями в телеграме, чуть позже планирую написать продолжение по данной тематики.

, ,

14 августа, 2024

Организация автодиплоя с BitBucket в WordPress

Доработка моего блога пошла быстрее и файлики стало неудобно заливать по штучно через ssh поэтому пришло время настроить автодеплой. В своих разработках я использую чаще всего git на Bitbucket.

Сделать автодеплой для связки Bitbucket+Wordpress не состовляет большого труда. Далее в статье я покажу как это достаточно просто можно организавать.

Для начала у вас должен быть создан репозиторий на битбаките. Выполняете пуш всех файлов вашего блога.

$ git clone git@bitbucket.org:<repository>
$ echo 'www/wp-config.php' >> .gitignore
$ echo '.env' >> .gitignore
$ git add *
$ git push 

Теперь переходим на сервер на котором планируем осуществлять автодеплой. Нам потребуется создать публичный ключ ssh для пользователя от которого будет осуществляться автодеплой ( он же должен быть владельцем файлов сайта на сервере ). Для моего сайта таким пользователем является пользователь www-data, но у него нет shell поэтому генерацию ключей нужно будет осуществить при помощи команды sudo

$ sudo -u www-data ssh-keygen -t rsa

Нажимаем Enter на все вопросы и далее копируем наш публичный ключ для того чтобы вставить его в настройки репозитория на битбаките

$ cat <dir_home_user_www-data>/.ssh/id_rsa.pub

Копируем в буфер обмена то что отобразилось и идем на битбакет с этим


Переходим в раздел Ключи доступа в настройках репозитория нашего сайта

Нажимаем Add key

Называем наш ключ доступа и заполняем нашим публичным ключем, который скопировали ранее

Теперь нам нужно создать хук автодеплоя и собственно сам скрипт, который будет делать автодеплой. Для этого переходим в раздел Веб-хуки в настройках нашего репозитория на битбаките и создаем новый веб-хук

Жамкаем на добавление веб-хука

Заполняем название веб-хука
Обязательно указываем адрес к нашему скрипту автодеплоя
Выбираем триггером PUSH событие ( наш скрипт будет вызываться когда в Битбакет будет запушены изменения ) и не забываем проставить статус активности веб-хука


Вот и все, теперь переходим к созданию скрипта деплоя.

<?php

$root_dir = realpath(exec('pwd').'/..');
$result = exec(sprintf('cd %s ; git fetch ; git pull', $root_dir));

После изменений внесенных в код необходимо закомитить и запушить наш скрипт в репозиторий.

Теперь мы можем выкачать репозиторий с сайтом на наш удаленный сервер.
Делаем клон рядом с нашей директорией на которую указывает настройки http сервера.
Чаще всего это /var/www

$ cd /var/www
$ sudo -u www-data git clone git@bitbucket.org:wikide/killercoder.git killercoder_git 

И переименовываем директории

$ mv killercoder killercoder_old ; mv killercoder_git killercoder

Теперь мы имеем рабочий сайт, который подключен к репозиторию
И при выполнение команды git push в ветку main будет происходить автоматический деплой на боевом сервере.

Конечно тут не решен вопрос миграций изменений, но это тоже можно будет реализовать достаточно просто. Для моих целей пока достаточно такого автодеплоя.

А если остались вопросы, то можете писать комментарии под статьей или писать мне сразу в теолеграм. Так же если вам нужна поддержка или разработка сайтов на WordPress, написание плагинов или любая помощь по вашему сайту на WordPress, то можете писать мне сразу в телеграм, а так же присоединяйтесь к каналу в телеграм чтобы следить за обновлениями на сайте.

Docker + Wordpress

, ,

31 июля, 2024

Поднимаем локально докер для WordPress

Так как появилась задача развивать дальше этот блог, то пришлось решить вопрос с локальным развертыванием сайта локально, поэтому открываю новую рубрику на сайте под названием яждевопс.

Когда-то давно еще во допотоные времена до ядерной войны в 18 веке лет 5 назад мы делали это при помощи вирутальной машины, которая работала через vagrant или вообще разворачивали всю экосистему локально, но сейчас времена наступили другие и появилась докеризация

Если кратко, то докер — это такая прикрасная штука, которая позволяет делать все что позволяла делать виртуальная машина, но более гибко и с меньшими ресурсными затратами. Например можно собрать себе экосистему для запуска определенного программного обеспечения и даже организовать свою изолированную сеть внутри докер системы на вашей локальной машине. О возможностях докера каждый может найти в любой поисковой системе, информации достаточно.

Тут же я хотел продемонстрировать простое решение на докере, которое позволяет развернуть локально такой простой блок на WordPress как этот блог. Итак поехали.

Для начала создаем файл .env с таким содержимым

# префикс, который мы будем использовать для наименования контейнеров в докере
PREFIX=wp

# пароль root для локального контейнера с mysql
MYSQL_ROOT_PASSWORD=somewordpress

# название базы данных root для локального контейнера с mysql
MYSQL_DATABASE=wordpress

# имя пользователя базы данных для локального контейнера с mysql
MYSQL_USER=wordpress

# пароль пользователя базы данных для локального контейнера с mysql
MYSQL_PASSWORD=wordpress

# хоста базы данных на боевом сервере
MYSQL_REMOTE_HOST=remote_host_address

# название базы данных на боевом сервере
MYSQL_REMOTE_DATABASE=remote_wp

# имя пользователя базы данных на боевом сервере
MYSQL_REMOTE_USER=user_db_read

# пароль пользователя базы данных на боевом сервере
MYSQL_REMOTE_PASSWORD=password_db_read

Тут все понятно по комментариям, единственное, что может вызвать вопрос это данные удаленного сервер mysql. Эти данные понадобятся для синхронизации с рабочей базой данных, о котором я напишу ниже. Стоит только отметить, что я рекомендую создать отдельную учетную запись на стороне боевого сервера у которой будет возможность только чтения из базы данных, чтобы в случае утечки этих данных эти данные не могли бы использовать для изменений данных на боевом сервере.

Далее создаем docker-compose.yml

services:
  db:
    container_name: ${PREFIX}-db
    # We use a mariadb image which supports both amd64 & arm64 architecture
    image: mariadb:10.6.4-focal
    # If you really want to use MySQL, uncomment the following line
    #image: mysql:8.0.27
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    expose:
      - 3306
      - 33060
    ports:
      - 3306:3306
      - 33060:33060
  wordpress:
    container_name: ${PREFIX}-wp
    image: wordpress:latest
    volumes:
      - ./www:/var/www/html
    ports:
      - 8082:80
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=${MYSQL_DATABASE}
      - WORDPRESS_DB_PASSWORD=${MYSQL_PASSWORD}
      - WORDPRESS_DB_NAME=${MYSQL_DATABASE}
      - WORDPRESS_DEBUG=false
volumes:
  db_data:

Это основной файл нашей докер системы при использовании которого будет запущено 2 контейнера, контейнер с базой данных mysql и контейнер с образом wordpress

Все настройки перечислять не буду ( почитаете документацию если будет кому нужно ) отмечу только то что в ports: мы биндим порты на локальную машину http будет доступен на порте 8082, а mysql на порту 3306 так же хочу отметить еще что в секции valumes: контейнера wordpress мы биндим локальную директорию ./www в которой будут хранится файлы wordpress. В нее нужно будет развенуть архив с wordpress или скопировать файлы wordpress с удаленного хостинга.

В итоге у нас получается вот такая директория проекта с файлом .env, docker-compose.yml и директорией www с файлами wordpress, если не хотите прописывать данные доступов к базе данных вручную, то перед запуском сборки докера удалите файл wp-config.php. Контейнер wordpress создаст его вручную и пропишет в него доступы из docker-compose.yml

Далее запускаем вот такую простую команду

$ docker compose up -d

Наслаждаемся процессом скачки образов и сборки контейнеров

Если вам повезло, то после этого можете зайти по адресу http://localhost:8082 откроется ваш wordpress

В принципе на этом можно было бы и закончить, но я настолько ленив, что мне захотелось создать несколько удобных команд для моего проекта, чтобы автоматизировать запуск, пересборку и установку докера, а так же синхронизацию удаленной базы данных ( не зря же я добавил в .env файл параметры MYSQL_REMOTE_*

Итак, чтобы автоматзировать рутинные задачи создадим Makefile.

Makefile — это такая крутая штука, которая была придумана еще в далкие времена, когда программы компилировали, а программисты еще знали как очищать в своих программах память от мусора и что такое язык С. В Makefile можно перечислять инструции которые потом можно выполнять в той директории в которой присутствует этот файл, вот такой Makefile у меня получился

include .env
export
.DEFAULT_GOAL = help
.PHONY: help

help:
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

up:
	@docker compose up -d

build:
	@docker compose up --build -d

down:
	@docker stop `docker ps -a -q`

shell:
	@docker exec -it $(PREFIX)-wp bash

drop-db:
	@docker exec -it $(PREFIX)-db mysql -e 'DROP DATABASE $(MYSQL_DATABASE) ; CREATE DATABASE $(MYSQL_DATABASE)' -uroot -p$(MYSQL_ROOT_PASSWORD)

sync: drop-db
	@ssh $(MYSQL_REMOTE_HOST) mysqldump -u$(MYSQL_REMOTE_USER) -p$(MYSQL_REMOTE_PASSWORD) $(MYSQL_REMOTE_DATABASE) | docker exec -i $(PREFIX)-db mysql -u$(MYSQL_USER) -p$(MYSQL_PASSWORD) $(MYSQL_DATABASE)

После этого чтобы запустить наш докер с wordpress достаточно будет ввести команду

$ make up

Для того чтобы пересобрать контейнеры

$ make down

Остановить докер

$ make down

И самая интересная команд, команда синхронизации базы данных докера с базой данных боевого сервера

$ make sync

Она удаляет полностью базу данных в докере и полностью забирает ее с боевого хостинга, после этой операции у вас в контейнере базы данных будет полная копия базы боевого сайта с wordpress

В целом это все. Если вдруг возникнут какие-то вопросы и замечания, то можете писать в комменатрии или мне в телеграм, так же если кому-то требуется разработка сайта на wordpress пишите сюда :)

, ,

30 июля, 2024

Обычный SSH тоннель

Понимаю, что банальность, но пусть будет.

Часто требуется подключится к базе данных mysql боевого сервера, но порт 3306 доступен только в localhost, для решения этой тривиальной задачи нам поможет ssh тоннель.

ssh -f -N -L 3307:localhost:3306 remote_host

Теперь в вашем localhost будет доступен порт 3307 через который вы сможете подключится к базе данных mysql на боевом хосте

-f запуск в фоне 
-N не выполнять команду (без нее и -f запустить шел на удаленном хосте)
-L перенаправление портов

апдейд:

Далее для удобства можем создать алиас для этого дела, чтобы быстрее можно было создать тоннель. Вот так это будет выглядеть для zsh под MacOS

$ vim ~/.zshrc

вставляем эту строку в конце файла

<br>alias create_tonnel="ssh -f -N -L 3307:localhost:3306 remote_host"

и выходим из vim

:wq