, , ,

29 мая, 2025

Маскировка трафика через Shadowsocks

В предыдущем посте, я описывал, что такое shadowsock и как он позволяет поднять зашифрованый канал связи через локальный прокси. В этой статье, я хочу поделится способом как можно замаскировать трафик shadowsock используя плагин v2ray. Подобная маскировка может быть полезной когда требуется обойти фильтры провайдера которые фильтруют трафик используя сложные алгоритмы DPI — глубокого анализа данных, что позволяет фильтрующим системам резать запросы отправленные через VPN или TOR, shadowsocks и плагин v2ray вполне могут решить эту проблему.

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

Что потребуется для настройки:

  • Отдельный хостинг, можете попробовать, например, вот этот
  • Локальный компьютер с Mac OS ( но на любой машине c *nix тоже заработает с минимальными изменениями )

Первое что потребуется сделать, это установка shadowsock о которой можно почитать тут — Устанавливаем Shadowsocks на свой сервер

Сразу же после того как вы установили shadownsock обезательно настройти фаервол сервера, чтобы он не блокировал трафик shadowsocks, я использую обычно ufw интерфейс к iptables, но можно настроить напрямую задав правила iptables

# Очистка всех правил iptables
ufw disable
ufw reset
ufw default deny incoming
ufw default allow outgoing

iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

# Добавление базовых правил
ufw allow 'OpenSSH'

# потребуется для настройки v2ray
ufw allow 'Nginx Full'

# этот порт оставляем для shadowsock
ufw allow 8080/tcp

# Проверем! Тут важно, если порт SSH не открыт то сессия будет завершена и вы не сможете подключиться снова
ufw list

# если все верно, то включаем 
ufw enable

Теперь нужно приступить к установки плагина для shadowsocks. В моей системе на сервере его не было поэтому я скачивал из репозитория, только перед скачиванием архива нужно проверить какая у вас система на сервере и выбрать подходящий архив для своей системы ( amd64/368/etc )

wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-linux-386-v1.3.2.tar.gz
tar -xzf v2ray-plugin-linux-368-*.tar.gz
mv v2ray-plugin_linux_amd64 /usr/local/bin/v2ray-plugin
chmod +x /usr/local/bin/v2ray-plugin

Теперь нужно поправить конифги сервера shadawsocks ( ss-server ) я создал конфиг в директории /etc для этого, но его можно создать где угодно, главное при запуске ss-server указать путь к нему

{
    "server":["0.0.0.0","::1"],
    "mode":"tcp_and_udp",
    "server_port":8080,
    "password":"password",
    "timeout":300,
    "method":"chacha20-ietf-poly1305",
    "plugin": "v2ray-plugin",
    "plugin_opts": "server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem",
    "fast_open": true
}

Теперь подробнее об параметрах:

  • server — тут нужно указать ip по которым можно будет подключаться к серверу по протоколу shadowsock для создания зашифрованого туннеля, 0.0.0.0 — разрешает все подключения для ip4, ::1 — разрешает все подключения для ip6 соответственно
  • mode — разрешает устанавливать соединение и по tcp и по udp
  • password — пароль подключения
  • method — метод шифрования, в данном случае приведен метод chacha20-ietf-poly1305 это быстрый безопасный метод потокового шифрования, если по каким-то причинам нужен другой, то список поддерживаемых методов можно узнать командой ss-server —help
  • plugin — подключаем плагин маскировки v2ray-plugin
  • plugin_opts — тут передаются настройки для плагина v2ray-plugin, но о них я напишу далее более подробно
  • fast_open — ускоряет tcp соединение

Тут требуется более подробно остановится на плагине и переданных опциях

v2ray-plugin для Shadowsocks — это плагин, который добавляет поддержку протокола VMess (из проекта V2Ray) к Shadowsocks, маскируя трафик под обычный HTTPS и улучшая обход блокировок. Для того чтобы он заработал потребуется реальный домен и сертификат безопасности ( подойдет letsencrypt ), поэтому на данном этапе нужно запустить web сервер и привязать к нему какой-либо домен или субдомен, например, вот так можно настроить nginx для v2ray:

server {
    if ($host = mydomain.ru) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name mydomain.ru;
    return 301 https://$host$request_uri;


}

server {
    listen 443 ssl;
    server_name mydomain.ru;

    location / {
        # Встраиваем плеер с радио (пример для Lofi Girl)
        add_header Content-Type text/html;
        return 200 '
<!DOCTYPE html>
<html>
<head>
    <title>Стрим 24 онлайн</title>
</head>
<body>
    <iframe 
	src="https://www.youtube.com/embed/jfKfPfyJRdk?autoplay=1"
        allow="autoplay; fullscreen" 
        allowfullscreen
    ></iframe>
</body>
</html>
        ';
    }
    ssl_certificate /etc/letsencrypt/live/mydomain.ru/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mydomain.ru/privkey.pem; # managed by Certbot

}

Как видите тут для примера я использовал генерацию сертификатов командой Cerbot но можно создать сертификат любым способом. После настройки web сервера и создания сертификатов под ваш домен требуется прописать пути к сертификату в настройках плагина в shadownsock.json

server;tls;host=mydomain.ru;cert=/etc/letsencrypt/archive/mydomain.ru/fullchain1.pem;key=/etc/letsencrypt/archive/mydomain.ru/privkey1.pem

тут важно отметить, что в конфигрурации сервера в опциях плагина вначале требуется указать server и еще один важный момент, опция не понимает путь к символьной ссылке поэтому потребуется указать путь на реальный файл ( не знаю почему так, но с указанием символьной ссылки у меня не получилось запуститься ) так же нужно будет учитывать это при обновлении сертификата ( например в кроджобе автоматического обновления сертификата можно указать так же выполнение своего скрипта который будет редактировать /etc/shadowsock.json и прописывать путь к актуальным обновленным сертфикатам

На этом в целом настройка конфига на сервере закончина. Далее потребуется перезапустить сам сервис. В прошлой статье про shadownsock я показывал как запустить ss сервер при помощи сервиса из пакета shadowsocks-libev но с добавлением плагина v2ray перестал работать запуск поэтому я решил написать свою службу для запуска, тут приведу интсрукции как создать новую службу и добавить ее в systemctl на сервер с Ubuntu

vim /etc/systemd/system/shadowsocks.service

и добавляем туда

[Unit]
Description=Shadowsocks Server with V2Ray-Plugin
After=network.target

[Service]
Type=simple

# Запуск сервера с подготовленным конфигом с плагином v2ray
ExecStart=/usr/bin/ss-server -c /etc/shadowsocks.json
Restart=always
RestartSec=3
Environment="HOME=/tmp"

# Если используете TLS-сертификаты:
ReadWritePaths=/etc/letsencrypt/live/mydomain.ru/
ReadWritePaths=/etc/letsencrypt/archive/mydomain.ru/
NoNewPrivileges=no

[Install]
WantedBy=multi-user.target
~                               

После добавления регистрируем новую службу командой

systemctl daemon-reload

И запускаем сервис

systemctl start shadowsocks
systemctl enable shadowsocks

На этом серверная часть готова и можно переходить к настройкам клиента.

Есть множество клиентов для разных систем и мобильных ОС, я решил использовать для себя самый простой консольный клиент ss-local а для этого потребуется установить его на ваш компьютер в зависимости от того какая у вас система, на маке это выглядет так

brew install shadowsocks-libev

И установка вручную плагина v2ray так как в репозитории brew его нет

wget https://github.com/shadowsocks/v2ray-plugin/releases/download/v1.3.2/v2ray-plugin-darwin-amd64-v1.3.2.tar.gz
tar -xzf v2ray-plugin-darwin-amd64-v1.3.2.tar.gz
sudo mv v2ray-plugin_darwin_amd64 /usr/local/bin/v2ray-plugin
sudo chmod +x /usr/local/bin/v2ray-plugin

И далее я реализовал небольшой скрипт bash для использования ss-local

vim ss-tunnel.sh
#!/bin/bash

# Путь к конфигурационному файлу
CONFIG_FILE="$HOME/.ss/config.json"
LOG_FILE="/tmp/ss-local.log"

# Проверяем наличие конфига
if [ ! -f "$CONFIG_FILE" ]; then
    echo -e "\033[31mОшибка:\033[0m Конфигурационный файл $CONFIG_FILE не найден."
    exit 1
fi

# Получаем локальный порт из конфига
LOCAL_PORT=$(jq -r '.local_port' "$CONFIG_FILE" 2>/dev/null || {
    echo -e "\033[33mПредупреждение:\033[0m Не удалось прочитать local_port, используем 1080"
    echo "1080"
})

ss_stop() {
   pkill -f "ss-local -c $CONFIG_FILE"
}

ss_start() {
    echo "Запускаем ss-local с конфигом $CONFIG_FILE..."
    ss-local -c "$CONFIG_FILE" -v &> "$LOG_FILE" &
    SS_LOCAL_PID=$!

    # Даем время на подключение
    for i in {1..5}; do
        echo -n "."
        sleep 1
    done
    echo
}

ss_check() {
    CHECK_URL="https://ifconfig.me"
    echo "Проверяем подключение через SOCKS5 (порт $LOCAL_PORT)..."
    if curl --socks5 "127.0.0.1:$LOCAL_PORT" --connect-timeout 10 -s "$CHECK_URL" &> /dev/null; then
        EXTERNAL_IP=$(curl --socks5 "127.0.0.1:$LOCAL_PORT" -s "$CHECK_URL")
        echo -e "\033[32mУспех!\033[0m Туннель работает. Ваш внешний IP: $EXTERNAL_IP"
        echo "Для остановки выполните: pkill -f 'ss-local -c $CONFIG_FILE'"
    else
        echo -e "\033[31mОшибка!\033[0m Не удалось подключиться через туннель."
        echo "Последние строки лога:"
        tail -n 5 "$LOG_FILE"
        kill -9 "$SS_LOCAL_PID" &> /dev/null
        exit 1
    fi
}

ss_log() {
    tail -f $LOG_FILE
}

ss_status() {
  if lsof -i :1080 >/dev/null 2>&1; then
    echo
    echo "🟢 PROXY: 1080"
    echo
  else
    echo
    echo "🔴 PROXY: DISCONECT"
    echo
  fi
}

case "$1" in
    start)
        ss_start
	;;
    stop)
        ss_stop
        ;;
    restart)
        ss_stop
        sleep 2
        ss_start
        ;;
    status)
        ss_status
        ;;
    log)
        ss_log
        ;;
    *)
        echo "Использование: $0 {start|stop|restart|status|log}"
        exit 1
esac

exit 0

Основная команда запуска тут ss-local -c «$CONFIG_FILE» -v &> «$LOG_FILE» &

в которую передается конфиг $CONFIG_FILE, я использую отдельную директорию в домашней директории пользователя для хранения конфига ~/.ss/config.json

Содержимое config.json на стороне клиента должно быть таким:

{
    "server": "<ip_server>",
    "server_port": 8080,
    "local_port": 1080,
    "password": "password",
    "method": "chacha20-ietf-poly1305",
    "plugin": "v2ray-plugin",
    "plugin_opts": "tls;host=mydomain.ru",
    "timeout": 300
}

Тут более менее понятно:

  • server — указываете ip вашего сервера
  • server_port — указываете порт сервера на котором запущен ss ( мы настроили выше сервер на раобту с портом 8080 )
  • local_port — указывается локальный порт клиента на котором будет стартовать sock5 служба
  • plugin — v2ray для маскировки трафика
  • method — должен совпадать с серверным методом шифрования
  • plugin_opts — тут нужно указать tsl; и ваш реальный домен на вашем хосте сертификаты которого прописаны в серверном конфиге

Все! После теперь можно добавить прав скрипту и можно попробовать запустить тоннель shadownsocks замаскерованный под https запрос

chmod +x ss-tonnel.sh
./ss-tunnel.sh 

После этого должна запуститься служба на порту 1080 через которую можно будет подключить приложение поддерживающие прокси соединения для установки безопасного замаскированного канала соединения. Проверить можно например исполнив команду curl с подключением через прокси на 1080 порту

curl --socks5 "127.0.0.1:1080 https://ifconfig.me

В ответ на команду должен прейти ответ с ip сервера

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

Для мониторинга соединения можно использовать небольшой скрипт в .zshrc который будет отображать активность proxy

vim ~/.zshrc

...
function proxy_status() {
  if lsof -i :1080 >/dev/null 2>&1; then
    echo "🟢 PROXY: %F{green}1080%f"
  else
    echo "🔴 PROXY: %F{red}DISCONECT%f"
  fi
}
...

# автообновление промпта
TMOUT=5

# и далее в удобное место добавляете PROMPT='... $(proxy_status) ... '
# для 

На этом пока что все.

, ,

18 января, 2025

Маскировка HttpClient Symfony под браузер

Всем привет! Иногда в проекте на Symfony удобно задать один единственный заголовок по-умолчанию чтобы везде где требуется вызвать HttpClient не нужно было бы каждый раз прописывать заголовок.

Делается это достаточно просто. Например часто нужно прикинутся браузером в своем скрипте, для этого достаточно задать верный заголовок User-Agent и никто не догадается, что запрос пришел не от браузера, а от вашего скрипта на PHP

Я представлю несколько вариантов.

Статичный вариант представляет из себя возможность добавить заголовок в настройки Symfony для

Добавляем в config/packages/framework.yaml следующий код:

framework:
    http_client:
        default_options:
            headers:
                User-Agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'

Таким образом где бы вы не вызвали в коде http client в Symfony в запросе будет передаваться заголовок User-Agent c данными из настройки

Можно сделать вариант поинтереснее, можно создать прослойку для http клиента проекта и внутри устанавливать заголовки запроса динамически выбирая из списка заголовки разных браузеров. Вот как это сделать:

<?php

namespace App\Service;

use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseStreamInterface;

class RandomUserAgentMiddleware implements HttpClientInterface
{
    private HttpClientInterface $httpClient;
    private array $userAgents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36',
        'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7; rv:118.0) Gecko/20100101 Firefox/118.0',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.67',
        'Mozilla/5.0 (iPhone; CPU iPhone OS 16_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1',
        'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 OPR/97.0.0.0'
    ];

    public function __construct(HttpClientInterface $httpClient)
    {
        $this->httpClient = $httpClient;
    }

    public function request(string $method, string $url, array $options = []): ResponseInterface
    {
        $options['headers']['User-Agent'] = $this->userAgents[array_rand($this->userAgents)];
        return $this->httpClient->request($method, $url, $options);
    }

    // Прокси для всех остальных методов
    public function stream($responses, float $timeout = null): ResponseStreamInterface
    {
        return $this->httpClient->stream($responses, $timeout);
    }

    public function withOptions(array $options): static
    {
        $new = clone $this;
        $new->httpClient = $this->httpClient->withOptions($options);
        return $new;
    }
}

И прописываем для прослойки декоратор http_client в services.yaml

services:
    App\Service\RandomUserAgentMiddleware:
        decorates: 'http_client'

Вызываем в коде проекта как обычно

class MySuperClass
{
    public function __construct(
        protected HttpClientInterface   $client,
        private readonly string $url
    )
    {
    }

    public function getData(): void
    {
        // Вот тут уже будет запрос с заголовком User-Agent реального браузера
        $response = $this->client->request('GET', $this->url);
        $data = $response->getContent();
        // ...
    }
}

, ,

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, но это уже немного выходит за рамки темы статьи.

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

, , , , , ,

22 декабря, 2024

Блокировка Газпромбанка, но выход есть.

После последних санкций империалистов заблокировали Газпромбанк. Как обычно самыми пострадавшими от этих так называемых антипутинских санкций оказались в первую очередь обычные простые рабочие люди, которые по мнению дегенератов из руководства США и ЕС должны тут же бросить свои дела и начать шатать режим которые получали зарплаты в рублях, но жили и работали за границей.

Если вы попали в такую ситуацию или ваши знакомые, то не стоит расстраиваться! Выход есть! И сейчас я расскажу как можно, получая деньги на карту Газпромбанка, выгоднее всего переводить средства в доллары США или любую другую валюту, которая вам необходима.

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

  1. Самый простой и быстрый, вам нужно зайти на один из самых популярных аррегаторов платежных системе — bestcgange.ru. Выбрать банк слева откуда вам нужно перевести и выбрать платежную систему или карту куда вы хотите перевести.

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

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

Следующий способ которым я хочу поделиться — это перевод денег через криптовалюту, т.е, вы сначала покупаете криптовалюту за рубли, а затем переводите деньги на карту банка, в котором еще не успели заблокировать Swift, например, платежную систему whitebird ( Белая птица ) Вообще эта система позволяет проводить финансовые операции между криптовалютами и банковскими картами, единственное условие, у вас должна быть карта в банке стран СНГ, но так же через нее вы можете создать себе карту и счет в Альфа банке Белорусь. Туда можете переводить деньги, затем уже в этом банке вы сможете открыть счет валютный и переводить со своего счета деньги на свою карту ( я это еще не проверял сам, но удивительно банк позволяет открывать счета гражданам России и вроде его пока не заблокировали в swift ). Но в данной статье, я бы хотел рассказать способ перевода денежных средств из Газпромбанка ( или любого другого российского банка ) на зарубежную карту. Для этого всего еще нам потребуется еще использовать криптовалюты. Схема простая:

Российская карта => P2P покупка стэйблкоина USDT => вывод USDT денежных средств на mastercard/visa через карту Белой птицы или тот же обменник на bestchange.ru или карту ByBit

Если вы выбираете вариант вывода средств через Альфа-банк Белорусь, для начала регистрируйтесь в Белой птице где вам так же будет необходимо пройти KYC (KnowYourCustomer) поэтому вам потребуется подготовить паспорт РФ и нужно будет отправить свое фото.

После этого вам нужно будет купить стейблкоины, я чаще всего использую стейбкоин USDT курс которого привязан к курсу доллара США и так как это USDT в сети Tron то операции с ним можно проводить с наименьшими комиссиями. Если вы не знакомы с криптовалютами и не знаете как пользоваться криптокошельком, то это обязательно нужно сделать, за блокчейном и криптовалютой в целом будущие планетарной финансовой систем поэтому вам все равно нужно будет с этим разобраться рано или поздно, лучше рано.. Обязательно подписывайтесь на мой телеграм канал куда я отправляю обновления на этом сайте, на котором в том числе пишу о том что из себя представляет криптовалюта и как ее можно использовать.

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

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

Далее я будт рассказывать про криптобиржу ByBit, ей я пользуюсь сам уже более года и в целом она полностью удовлетворяет моим потребностям. Там же я пользуюсь сервисом P2P для покупки стейблкоина USDT.

Итак, регистрируйтесь по ссылке на ByBit и после регистрации для совершение финансовых операций, вам нужно слить ваши персональные данные товарищам майорам и господам из ЦРУ пройти KYC. После успешного прохождения верификации KYC, у вас появится доступ ко всем сервисам бирже в том числе к P2P обмену.

Если говорить о том что же из себя представляет P2P (point-to-point, от человека человеку), то это по-сути торговля между людьми, биржа ничего с этого не имеет так как комиссия отсутствует, вы сами можете выбрать того продавца, который наилучшем образом вам подходит, по способу перевода, по лимитам, по стоимости USDT. Биржа лишь предоставляет инфраструктуру сервиса, замораживает денежные средства на своей стороне и после подтверждения операции и подтверждении о согласии всех сторон переводит вам USDT и закрывает сделку.

Вот так выглядит экран с различными продавцами USDT

Я отметил на скриншоте цифрами на что следует обратить внимание при обмене. Итак.

  1. Валюта которую нам нужно купить, в данном случае это будет USDT
  2. Валюта на которую мы хотим купить, в данном случае нам нужно купить за рубли
  3. Способ оплаты, деньги в рублях у нас лежат на счету Газпрома, именно этот способ оплаты и выбираем
  4. Имя продавца
  5. Количество выполненных сделок у данного продавца
  6. Количество выполненных успешных сделок у продавца. В целом 94% это хороший результат, который может говорить о том, что продавец достаточно надежный.
  7. Стоимость USDT в рублях. Тут стоит отметить, что продавец сам вправе выставлять стоимость USDT. Тут видим, что за 1USDT (1$) продавец хочет — 104,19 в целом это не самый плохой вариант.
  8. Количество доступных USDT у продавца, в данном случае продавец продает 255 USDT (255$)
  9. Лимиты, в данном случае лимит установлен на весь доступный объем USDT те продавец согласен на сделку только если у него купят весь оставшийся объем в размере 255 USDT

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

  1. Количество сделок у продавца
  2. Процент успешных сделок
  3. Количество доступеых USDT
  4. Лимиты ( в данном случае от 50 до ~145 тысяч рублей
  5. Список доступных платежных систем, в данном случае видно, что газпромбанк так же доступен.
  6. Цена USDT у данного продавца
  7. Сумма в рублях на которую вы хотите купить USDT
  8. Количество USDT которую вы получите после успешной выполненной сделки

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

  1. время сделки, еслс за указанный период сделка не совершится, то она будет отменена, так же можно отменить сделку нажав на кнопку внизу экрана — Отменить ордер. Только внимание! Если вы отмените 2 ордера, то на сутки вам заморозят покупку на P2P. Если не уверены, что готовы совершать сделку не переходите на этот экран.
  2. Стоимость 1 USDT в рублях
  3. Сумма сделки. Именно эту сумму нужно будет перевести по реквизитам продавца, чтобы он перевел вам USDT
  4. Сумма USDT которую вы получите после успешной сделки.
  5. Наш Газпромбанк в списке способов оплаты, выбираете его и либо вам сразу отобразятся реквизиты банка на который нужно будет перевести сумму в 150000 руб или будет написано что реквизиты требуется получить в чате.
  6. Чат с продавцом. Тут важно понимать одно. Когда вы создали данный ордер, то деньги продавца уже заблокированы на бирже до успеха ордера или до отмены ордера. Важно! Не переходите не по каким внешним ссылкам, которые вам может отправить продавец и не оплачивайте ничего вне рамках коммуникаций бирже. В случае если переписки с продавцом будут происходить в каких-то других чатах и системах и будут произведены мошеннические действия со стороны продавца, у бирже не будет информации о том чтобы подтвердить, что вы совершили платеж. Поэтому общайтесь только в чате биржи.

После совершения платежа, продавец запрашивает подтверждение в виде квитанции об оплате, чаще всего требуется формат PDF ( это для того чтобы обезопасить себя от мошеннических действий со стороны покупателя )

Итак, производим оплату, скидываем в чат квитанцию PDF и нажимаем кнопку — Платеж выполнен. Продавец со своей стороны проверяет, что платеж прошел и соглашается со сделкой. После этого деньги оказываются на вашем счету ByBit.

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

В принципе после этого вы можете вывести их на карту Visa, Mastercard в любом проверенном платеже на BestChange или можете совершить вывод через платежный сервис WhiteBird ( все комиссии и оплаты составят 1,5% по банковским картам Белоруси и чуть больше для других стран СНГ ), но для этого вам потребуется привязать карту Visa к системе. Карта Visa должна быть выпущена в СНГ, к счастью можно сделать карту в стране в которой пока не под санкциями и уже с нее переводить деньги на зарубежные карты через Swift. Так же можно поменять USDT в офлайн обменнике на доллары или валюту, которая вам нужна с более выгодным курсом, еще есть вариант вывода USDT напрямую с ByBit на карту, но с небольшой комиссией, ну и конечно так же можно продать USDT на доллары на P2P бирже. Так же при помощи ByBit можно оформить себе карту и расплачиваться непосредственно криптовалютой с нее.

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

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