Как написать свой прокси сервер

Крупные VPN-сервисы первыми попадают под блокировку. Поэтому, у нас два варианта:

  • Пользоваться услугами компаний-середнячков.
  • Научиться ставить VPN и прокси самостоятельно.

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

На сайтах-агрегаторах VPN:

  • vpnpro.com
  • vpnreports.com
  • vpnmentor.com
  • vpntesting.com с таблицей ТОП-50 VPN.

Таблица доступных в РФ VPN-сервисов:

Хочу сделать все своими руками. С чего начать?

Для начала, нужно купить зарубежный сервер VPS/VDS. В среднем сервер стоит 1.5-3$ в месяц.

Где искать зарубежные серверы?

На сайтах-агрегаторах VPS/VDS:

  • serverhunter.com
  • exoticvm.com
  • vpschecker.com
  • vpsbenchmarks.com/screener
  • en.metadedi.net

Когда сервер куплен, можно приступать к установке VPN/прокси.

1. OpenVPN и Pritunl

Pritunl – свободное ПО, предоставляющее веб-интерфейс для управления OpenVPN и Wireguard.

Простая видеоинструкция по установке OpenVPN (Pritunl) на Ubuntu:

1.1. Установка Pritunl

Обновим список пакетов и систему (в статье используется Ubuntu 20):

        sudo apt update && sudo apt upgrade
    

Добавим Pritunl в репозиторий:

        sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com --recv 7568D9BB55FF9E5287D586017AE645C0CF8E292A

sudo tee /etc/apt/sources.list.d/pritunl.list << EOF
deb https://repo.pritunl.com/stable/apt focal main
EOF
    

Установим Pritunl:

        sudo apt update
sudo apt install pritunl
    

Запустим и активируем Pritunl:

        sudo systemctl start pritunl
sudo systemctl enable pritunl
    

Проверим, запущен ли Prtinul:

        sudo systemctl status pritunl
    

Если все работает, то увидим следующую запись:

        ● pritunl.service - Pritunl Daemon
     Loaded: loaded (/etc/systemd/system/pritunl.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-10-26 15:35:10 EEST; 15s ago
   Main PID: 3716 (pritunl)
      Tasks: 19 (limit: 2282)
     Memory: 283.7M
     CGroup: /system.slice/pritunl.service
             ├─3716 /usr/lib/pritunl/bin/python /usr/lib/pritunl/bin/pritunl start
             └─3792 pritunl-web
    

Добавим MongoDB в репозиторий:

        sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list << EOF
deb https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse
EOF

wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
    

Установим MongoDB:

        sudo apt update
sudo apt-get install mongodb-org
    

Запустим MongoDB:

        sudo systemctl start mongod
sudo systemctl enable mongod
    

Проверим, запущен ли MongoDB:

        sudo systemctl status mongod
    

Если сервис запущен, то мы получим следующий вывод:

        ● mongod.service - MongoDB Database Server
     Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-10-26 15:59:20 EEST; 54s ago
       Docs: https://docs.mongodb.org/manual
   Main PID: 68587 (mongod)
     Memory: 64.1M
     CGroup: /system.slice/mongod.service
             └─68587 /usr/bin/mongod --config /etc/mongod.conf
    

Зайдем на сервер по IP-адресу https://IP-address.

🛠 Как за 3 простых шага создать свой VPN и прокси-сервер

Чтобы получить установочный ключ, введем в терминале:

        sudo pritunl setup-key
    

Установка Pritunl

Установка Pritunl

Сгенерируем пару логин/пароль:

        sudo pritunl default-password
    

Зайдем еще раз на сервер по IP:

Вход в веб-интерфейс Pritunl

Вход в веб-интерфейс Pritunl

1.2. Настройка Pritunl

Чтобы начать пользоваться Pritunl нужно:

  1. Создать сервер Pritunl.
  2. Создать организацию и прикрепить ее к серверу.
  3. Создать пользователя и прикрепить его к организации.

Создание сервера

Чтобы создать сервер, перейдем во вкладку ServersAdd Server и активируем вкладку Advanced:

Создание сервера в Pritunl

Создание сервера в Pritunl

Добавим сервер.

Создание организации

Перейдем во вкладку UsersAdd Organization и добавим новую организацию:

Создание организации в Pritunl

Создание организации в Pritunl

Прикрепим организацию к серверу. Для этого перейдем во вкладку ServersAttach Organization:

Прикрепление организации к серверу в Pritunl

Прикрепление организации к серверу в Pritunl

Нажмем на кнопку Start для запуска сервера.

Создание пользователя

Чтобы создать пользователя, перейдем во вкладку UsersAdd User:

Создание пользователя в Pritunl

Создание пользователя в Pritunl

1.3. Раздаем ключи

Чтобы подключиться к VPN, скачаем и установим клиент для своей ОС pritunl.com/platforms. Вернемся к серверу и перейдем во вкладку UsersAdd User, и кликнем по значку цепочки:

Раздача ключей в Pritunl

Раздача ключей в Pritunl

Скопируем URI-ссылку:

Раздача ключей в Pritunl

Раздача ключей в Pritunl

Вставим URI-ссылку в клиент и подключимся к VPN:

Соединение с сервером Pritunl

Соединение с сервером Pritunl

Мы подключились к серверу.

2. Shadowsocks и Outline

Outline создан стартапом Jigsaw, примкнувшим к компании Google. Под капотом у Outline находится протокол Shadowsocks, который маскирует данные под HTTPS-трафик.

Для установки Outline потребуется Docker.

2.1. Установка Docker

Обновим список пакетов и систему:

        sudo apt update && sudo apt upgrade
    

Установим пакеты, которые позволят apt устанавливать пакеты через HTTPS:

        sudo apt install apt-transport-https ca-certificates curl software-properties-common
    

Добавим ключ GPG для репозитория Docker в систему:

        curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    

Добавим репозиторий Docker в систему:

        sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
    

Обновим список пакетов:

        sudo apt update
    

Установим Docker:

        sudo apt install docker-ce
    

2.2. Установка менеджера Outline

C помощью менеджера Outline можно добавлять и удалять сервера и раздавать ключи. Скачаем менеджер по ссылке getoutline.org/ru/get-started:

Установка менеджера Outline

Установка менеджера Outline

Выберем Настройте Outline где угодно:

Установка Outline на сервер

Установка Outline на сервер

Чтобы установить Outline, введем на сервере команду из пункта 1:

Команда для установки Outline на сервер

Команда для установки Outline на сервер

После установки Outline мы получим строчку с инфой о нашем Outline-сервере в формате JSON:

🛠 Как за 3 простых шага создать свой VPN и прокси-сервер

Скопируем JSON-строку, вставим ее во второе поле Менеджера Outline и нажмем Готово.

🛠 Как за 3 простых шага создать свой VPN и прокси-сервер

Теперь мы можем поделиться ключом доступа с кем угодно:

Менеджер Outline

Менеджер Outline

2.3. Раздаем ключи

Скачаем и установим клиент Outline:

Установка клиента Outline

Установка клиента Outline

Откроем менеджер Outline и скопируем ключ в клиент Outlline:

Подключение к серверу Outline

Подключение к серверу Outline
Подключение к серверу Outline
Подключение к серверу Outline

Связь установлена:

🛠 Как за 3 простых шага создать свой VPN и прокси-сервер

Если в Windows 10 клиент Outline не подключается к серверу, то нужно отключить Hyper V. Для этого откроем PowerShell от имени администратора и введем:

        Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Hypervisor
    

***

В этой статье мы научились:

  • создавать VPN-соединение с помощью Pritunl;
  • создавать прокси-сервер, используя Outline;
  • раздавать VPN и прокси другим пользователям.

Материалы по теме

  • Как поставить Joomla 4 на выделенный сервер VDS/VPS?
  • Как работает прокси-сервер: максимально простое объяснение
  • Что такое кибербезопасность и почему за этой профессией будущее?
  • Зашифрованный трафик тоже можно вскрыть: рассказываем, как сделать это безопасно
  • GPG и все-все-все: настраиваем шифрование переписки за 10 минут по методу Кристофера Робина

Время на прочтение
7 мин

Количество просмотров 17K

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

Итак, задача:
Хочется, чтобы каптчу вводить не приходилось. Хоть если играешь сам, хоть если играет за тебя бот, если ты спишь.
Дополнительное условие: 40 часов времени (ибо паника на корабле).
Желательное условие: установочный файл под Windows.
Ещё одно желательное условие: результат должен занимать не более мегабайта.

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

Итак, что же делать?

Попытка 1

Написать системную тулзу, которая бы перехватывала HTTP запросы и ответы от всёх установленных программ, и фильтровала бы те ответы, на которые бы требовалось ввести каптчу, вводя её самостоятельно. Над программой, которая в том числе должна была решать и эту задачу корпели примерно полгода два белорусских программиста, меняя платформу с C на C#, и потом на Java, и мирясь с тем, что им может понадобится установленный на машину OpenSSL. Задача каждый раз обрастала ненужными подробностями. Ну, в целом, не вышло.

Попытка 2: Сам, всё сам

Вполне понятно, что способов не так много, и выбор встал только между SOCKS прокси и HTTP прокси. Через некоторое время стало понятно, что SOCKS прокси поддерживают далеко не все пользовательские приложения, и выбор стал однозначным.

Выбор платформы

Выбор был не сложен, особенно учитывая попытку 1. C и C# были быстро отметены, учитывая полное отсутствие опыта. Были выявлены следующие, богатые необходимыми библиотеками, платформы:

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

Python Как известно, работает везде и всё включено (batteries included). Весит 7Мб. По современным меркам, конечно, немного, но всё же хотелось компактнее. Остался вопрос, как этот инсталлятор внедрить в инсталлятор моей утилиты. Не знаю, как это делается у питоновских приложений, возможно, намного проще, но инсталлятор в инсталляторе я как-то раз уже делал и больше не хочу.

Ruby На момент начала моих поисков отсутствовал одношаговый инсталлятор под винду. Целиком и полностью. Сейчас есть, подразумевает установку MinGW, MSYS и прочего, при установке могущего испугать юзера. Вес 7Мб.
Про инсталлятор в инсталляторе вопрос остался.

Lua Очень давний и популярный среди скриптовщиков С++ игр язык. Вялое community, разрозненные библиотеки. Вес кастомной сборки VM в нужными библиотеками — всего 800Кб. Инсталлятор не предоставляется, есть набор exe файлов, которым в качестве параметра передаётся lua скрипт для его запуска. То, что нужно, так ещё и откомпилено под Win, MacOS, Linux, каждое из них в версиях 32 и 64 отдельно. То, что надо.

Итак, я взялся за изучение Lua (сбылось новогоднее пожелание, я изучил новый язык программирования).
Язык обладает чудесными свойствами, такими как:
— sandboxing (в ruby был только патч для версии 1.8.5): позволяет запускать сторонний код, ограничивая ему окружение;
— coroutines (типа ruby fibers из 1.9): позволяет сделать очень легковесную кооперативную многозадачность;
— очень простые (точнее, простая — есть только ассоциативный массив) структура данных, которой, как оказалось, хватает, для выполнения большинства задач по обработке данных;
… ещё много всего, тяжко так в одном посте.

Проще всего было сделать такую систему в виде фильтрующего запросы и ответы HTTP прокси сервера, что и было решено сделать (от добра добра не добра).

Идея проста: повесить сервер TCP, слушать, что клиент просит, разбирать заголовки HTTP, искать HOST, убирать HTTP header «Proxy-Connection», отсылать запрос тому, кому он предназначался, получать ответ, направлять клиенту и т.п.

Ответ сервера нужно фильтровать, и делать это можно, если сервер не применяет HTTPS, а он по счастью его не применяет. Сделать это оказалось довольно просто, достаточным оказалось написать сокращённый до 190 строк Lua аналог mechanize для Ruby, который делает с заголовками и телом запроса что ни взбредёт в голову, позволяя писать какие хочется фильтры для HTTP запросов.

Ну, в этом случае нам надо было избавиться от вредной reCAPTCHA, для чего всего лишь потребовалось определить:
— к странице ли травиана щёл исходный запрос (и запрашивалась ли страница HTML):
string.find(request.uri(), 'travian') and mimetype and string.find(mimetype, 'text/html')

— содержалась ли на результирующей странице каптча вместо «полезных» игровых данных:
local captcha, captcha_key = string.match(response.body(), '<iframe src="(http://api.recaptcha.net/noscript??(k=[%a%d_]+&lang=en))')

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

В итоге, скачивалась картинка каптчи, отправлялась индусам (2 раза на всякий случай), полученные через 5-10 секунд ответы сравнивались, и если они были одинаковыми, то результат отправлялся травиану HTTP POST запросом, на что жертва выдаёт страницу, радостно сообщая, что мы, оказывается, человек, и кучу «полезных» игровых данных. Эту страницу мы и показываем ничего не подозревающему клиенту, который мог заметить лишь некоторую паузу. В пессимистичном случае несовпадения картинка отправлялась индусам ещё раз, и так далее до того момента, пока не получалось хотя бы два одинаковых решения, остальные отправлялись в службу поддержки на возврат денег (практически никакой халявы для индусов).

Итак, вот оно, решение и есть.

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

Ну что же, для этого нашлось целых три разных библиотеки для создания асинхронного TCP сервера. То есть — ждём входящее соединение, получаем кусок данных, передаём управление диспетчеру, смотрим есть ли ещё входящие соединения или открытые соединения для которых есть данные (select/kpoll/epoll), передаём управление по очереди.

Увы и ах, поскольку все такого рода соединения происходят на локальной машине, то всё это происходит почти мнгновенно. А медленные соединения — исходящие. Подковырять существующие библиотеки (copas, asok), которые предназначены для мультиплексирования входящих соединений, оказалось сложнее, чем писать свою. И я написал небольшую (272 строки) свою. Помимо того, что все входящие и исходящие соединения работают асинхронно, так можно добавлять ещё любые корутины (поправьте меня, люди с профильным образованием) в пул, работающий в общем цикле.

Ну вот, всё стало работать параллельно, а по скорости лишь незаметно отставать от того, как это работает без прокси.

Как же велико было моё удивление, когда я получил от сервера страницу с (в том числе) заголовками:
Content-Encoding: gzip
Transfer-Encoding: chunked
и собственно полные кракозябры в качестве тела ответа.

Первая мысль была отключить в запросе Accept-Encoding, чтобы сервер не пытался паковать данные, и переделать HTTP 1.1 в HTTP 1.0, чтобы не посылало «чанками». Но подумал об падении скорости и увеличении трафика, и сжалился над пользователями.
Вышло так:
if headers(pipe, target)['Transfer-Encoding'] == 'chunked' then
target.body = dechunk(target.body)
end

function dechunk(chunkie)
local chunk_size
local chunk
local chunks = {}
chunkie, chunk_size = readline(chunkie)

while chunk_size and tonumber(chunk_size, 16) > 0 do
chunkie, chunk = readbytes(chunkie, tonumber(chunk_size, 16))

table.insert(chunks, chunk)
chunkie, chunk_size = readline(chunkie)
if not chunk_size or chunk_size == '' then -- sometimes there's a crlf, sometimes not
chunkie, chunk_size = readline(chunkie)
end
end

return table.concat(chunks)
end

Ушёл читать матчасть. Слава богу, по этим пунктам документации порядочно.
Склеиваем «чанки», получаем gzip файл (иногда deflate, но мне не встречался пока). Распаковываем (спасибо David Manura за библиотеку).
Распаковка вышла ещё проще:
if headers(pipe, target)['Content-Encoding'] == 'gzip' and #target.body > 0 then
local decoded = {}
gzip.gunzip {input=target.body, output=function(byte) table.insert(decoded, string.char(byte)) end}
target.body = table.concat(decoded)
end

Осталось немного
— сделать HTTPS-туннелирование для HTTPS сайтов (слава богу, OpenSSL бандлить не надо, просто данные прозрачно передавать туда-сюда):
if request.method() == 'CONNECT' then
local sent_to_server, err = client.send("HTTP/1.0 200 Connection establishedrnProxy-agent: BotHQ-Agent/1.2rnrn")
print('https transparent connection')
https(client, server)
return
end

local function https(client, server)
close_callback = function()
client.close()
server.close()
end

client.receive_subscribe(function(data)
server.send(data)
end, close_callback)

server.receive_subscribe(function(data)
client.send(data)
end, close_callback)
end

— положить в инсталлятор:
В целом приключения с запуском 7zip sfx на Heroku стоят отдельного поста. Радость победы затмевает любые сложные моменты разработки.

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

В итоге:
Сам прокси сервер на 71 строку здесь.
Асинхронная библиотека TCP-сервер-клиент на 272 строки тут.
Некий аналог HTTP клиента на 190 строк.
Фильтр для разгадывания каптчи на 150 строк тут.
Установочный файл размером менее мегабайта.

Уверен, такой штуке найдётся много полезных применений, начиная от не очень хороших, типа спамилок с «автоматической» разгадкой каптчи, до полезных, когда нужно гибко отфильтровать пользовательский трафик скриптом. Приведу простейший скрипт, не позволяющий пользователям, подсоединённым через прокси, соединяться с vk.com:
module(..., package.seeall)
function filter(request, response)
response.set_body('')
end

function pre(request, response)
return string.find(request.uri(), 'vk.com')
end

С приближающимся выходом lua 5.2 снимется ограничение на вызов метаметодов из корутин, и библиотеки можно будет сделать более красивыми, например, уйдут методы http.set_body, и многое другое.

Потратьте всего десять минут и пару долларов в месяц, чтобы стать свободными от блокировок.

Предисловие

В последнее время в российском интернете участились блокировки сайтов. Если ранее в основном блокировались оппозиционные СМИ, то сейчас под горячую руку Роскомнадзора начали попадать даже социальные сети (Facebook, Twitter), а также просто неугодные властям сайты, вроде страниц правозащитных организаций.

Многие люди начали задумываться о поиске способов обхода блокировок, но в основном эти способы заканчиваются установкой дорогих VPN-сервисов, которые часто не работают должным образом, ограничивают траффик и не имеют гибких настроек, если, скажем вы хотите блокировать только несколько сайтов и только в определенном браузере. И это не говоря уже о том, что 99% инструкций предназначены только для ОС Windows.

Поэтому в данной статье я расскажу вам о двух способах обходах блокировок на Mac OS, при этом не тратя много времени и денег. Перед написанием статьи я прошел все шаги самостоятельно, и постарался описать их максимально понятно даже для тех людей, кто никогда не пользовался командной строкой.

Содержание

► Кстати!

Способ № 1. Самый гибкий и предпочтительный

I. Аренда VPS/VDS

Первым делом нам нужно арендовать наш собственный VPS/VDS (виртуальный выделенный сервер). Сервер для наших нужд подойдет не любой, а только тот, который находится за пределами РФ. В интернете можно найти множество хостинг-провайдеров, которые предоставляют данную услугу. Я нашел и протестировал для вас три самых дешевых хостера, которые полностью совместимы с нашим способом.

  • Сервер находится в Нидерландах;
  • Скорость соединения: 500Мбит/c;
  • Стоимость самого дешевого сервера: 330 рублей в месяц;
  • Поддерживает оплату российскими картами, а также через сервисы QIWI и ЮMoney.

— — —

■ Айхор – не рекомендую:

upd от 16 марта: Подняли цены в два раза (со 120₽ до 240₽) А еще у данного хостинга, хоть и находятся сервера в Европе, но почему-то выдается российский ip-адрес (из-за чего не открываются некоторые сайты, которые вручную ставят блок на российские ip-адреса, вроде того же TJournal).

upd от 08 марта: Хостинг перестал работать.

* * *

Инструкция по аренде VPS (одинаковая для обоих хостеров):

  1. Регистрируемся на сайте;
  2. Подтверждаем наш email-адрес (обязательно);
  3. Выбираем дата-центр Нидерланды;
  4. В качестве ОС выбираем Ubuntu 18.04 или новее;
  5. Оплачиваем;
  6. Ждем, когда сервер станет готов к использованию;
  7. Получаем на email данные с ip-адресом, а также логином и паролем для входа на наш VPS (если на email ничего не пришло, то данные всегда можно найти, зайдя в ЛК в раздел «Поддержка» в пункте «Тикеты», зайдя в тему «Создан новый сервер»).

* * *

II. Подготовка Terminal

Шаг 1. Открываем Terminal (найти его можно, вызвав Spotlight нажав комбинацию на клавиатуре CMD+Space).

Шаг 2. Устанавливаем Homebrew, выполнив команду в Terminal:

/bin/bash -c «$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)»

Шаг 3. Устанавливаем wget, выполнив команду в Terminal:

$ brew install wget

* * *

III. Настройка VPS/VDS

Шаг 1. Присоединяемся к нашему VPS:

  1. Запускаем Terminal;
  2. Правой кнопкой мыши по ярлыку и выбираем New Remote Connection (Новый удаленный доступ);
  3. Выбираем тип соединения SHH;
  4. Нажимаем на плюсик справа;
  5. Вводим ip-адрес нашего VPS;
  6. В поле user (пользователь) вводим имя (по умолчанию root);
  7. Нажимаем Connect (Присоединиться);
  8. Вводим пароль, печатая, либо вставляя при помощи CTRL+V и Enter (в поле пароль не отображается);
  9. Если все правильно, то вы увидите слова приветствия в окне Terminal.

Шаг 2. Устанавливаем программу 3Proxy для настройки прокси-сервера, выполняя команды в Terminal:

1. Скачиваем готовый скрипт для установки:

wget —no-check-certificate https://raw.github.com/SnoyIatk/3proxy/master/3proxyinstall.sh

2. Выставляем права доступа:

chmod +x 3proxyinstall.sh

3. Устанавливаем ПО (процесс занимает около пяти минут):

./3proxyinstall.sh

Шаг 3. Редактируем файл авторизации, выполнив команду в Terminal:

sudo nano /etc/3proxy/.proxyauth

Шаблон: user:CL:password
Вместо user – пишем имя (пример: vasya), вместо password – пишем пароль (пример: 1234567q). Буквы CL оставляем как есть.
Пример: vasya:CL:1234567q

Шаг 4. Применяем настройки и запускаем прокси-сервер, выполнив команды в Terminal:

sudo systemctl daemon-reload
sudo systemctl enable 3proxy
sudo systemctl start 3proxy

IV. Результат

Поздравляю! Теперь у вас на руках есть данные готового HTTP[S] прокси-сервера с собственным ip-адресом, открытым портом 9999, а также логином и паролем.

Теперь вы можете использовать этот прокси-сервер:

  • В настройках Сети (и тогда через ваш прокси будет проходить весь траффик, включая скачивание файлов, а также обновление приложений через AppStore, серфинг в любых браузерах и многое другое);
  • В различных программах для анонимизации;
  • На вашем iPhone или любом другом смартфоне;
  • В расширении Runet Censorship Bypass для Google Chrome (собственно ради этого все и затевалось).

* * *

Как я уже написал выше, вся настройка VPS затевалась ради использования его в связке с расширением Runet Censorship Bypass. Ниже я напишу инструкцию как сделать так, чтобы фильтрация траффика через прокси происходила только на заблокированных РКН сайтах, а не везде подряд (что значительно ускорит ваш серфинг в интернете). Однако, это сработает только если вы пользуетесь нормальным браузером под названием Google Chrome, а не ограниченным недоразумением под названием Safari.

* * *

Инструкция по настройке расширения RCB:

  1. Скачиваем расширение Runet Censorship Bypass для Google Chrome;
  2. Переходим в настройки расширения (левым щелчком мыши по нему);
  3. В категории PAC-script меняем пункт с Antizapret на Anticensority;
  4. Переходим в категорию Own proxies;
  5. Выбираем пункт «Использовать СВОИ прокси»;
  6. Выбираем протокол – PROXY/HTTP;
  7. В «домен/IP» вписываем ip-адрес нашего прокси-сервера;
  8. В номер порта пишем 9999;
  9. Нажимаем справа от порта плюсик + (обязательно!);
  10. Если ниже нашего прокси создалось лишнее пустое поле, то удалите его.

Теперь весь обход блокировок будет происходить через наш прокси-сервер.

А самое главное, вы теперь сможете принудительно включать или отключать прокси на любом сайте (а также импортировать и экспортировать списки сайтов, даже если у вас их тысячи). Делается в категории Exceptions в настройках расширения. При нажатии на у вас откроется редактор списка сайтов, где можно выставлять черные и белые списки.

* * *

Установка расширения Proxy Auto Auth для Google Chrome

После того, как мы закончили предыдущие пункты, осталось установить последнее расширение. Называется оно Proxy Auto Auth. Оно нам очень пригодится в одном маленьком деле. Дело в том, что, так как, мы сделали наш прокси защищенным, то при серфинге в интернете, сайты начнут постоянно запрашивать логин и пароль от прокси, и чтобы не вбивать их вручную, нам понадобится сделать это всего один раз, а именно:

  1. Скачайте расширение из официального источника;
  2. Установите, и затем вбейте туда ваши логин и пароль от прокси.

Если вы работаете с прокси в режиме Инкогнито, то не забудьте также разрешить расширению работать в Инкогнито.

* * *

V. Дополнительная информация

Если нужно перезапустить программу 3Proxy, выполняем команду в Terminal:

systemctl restart 3proxy

Если нужно проверить статус сервера, выполняем команду в Terminal:

systemctl status 3proxy.service

Если нужно удалить прокси-сервер, выполняем команду в Terminal:

wget —no-check-certificate https://raw.github.com/SnoyIatk/3proxy/master/3proxyuninstall.sh chmod +x 3proxyuninstall.sh ./3proxyuninstall.sh​

Способ № 2. Для совсем ленивых

В данном способе мы будем использовать программу, которая имеет всего два варианта фильтрации траффика:

  • Фильтровать весь траффик компьютера (из-за этого скорость соединения будет часто падать, не говоря о растущем пинге и прочих неудобствах);
  • Фильтровать только сайты из пользовательского списка (что тоже не очень удобно, да и работает настолько криво, что при внесении сайта, скажем Медузы, программа запоминает лишь один ip-адрес сайта, а не диапазон, из-за чего внеся сайт, он все равно может не открываться).

Очень не рекомендую данный способ, если вы, конечно, не совсем обленившийся человек, который просто ищет более дешевую альтернативу VPN-сервисам и готовы мириться с просадками в скорости.

* * *

I. Аренда VPS/VDS

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

* * *

II. Установка программы Amnezia

Программа Amnezia появилась в интернете всего несколько лет назад и была создана российскими разработчиками. Программа полностью бесплатная и имеет полностью открытый код (причем не только клиентской части, но и серверной в том числе). Установка и настройка происходит в пару кликов.

  • Скачиваем программу с официального сайта;
  • Далее следуем инструкции с официального сайта (все картинки на сайте можно свайпать, зажав левую кнопку мыши)

III. Дополнительная информация

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

Кстати!

Уже в ближайшем будущем станет возможна полная изоляция российского интернета. Если это произойдет, то ни VPN, ни VPS, ни прокси-серверы не смогут вам помочь выйти в глобальный интернет.

Журналист издания The Insider на днях взял большое интервью у одного из сооснователей Рунета, в котором тот подробно рассказал какими новыми методами будет действовать Роскомнадзор в сотрудничестве с Ростелекомом. Что характерно, сразу после публикации статьи сайт издания был заблокирован.

Прочитать статью можно по одной из ссылок ниже:

  • Оригинальный сайт (недоступен): https://theins.ru/politika/248511
  • Новый домен сайта: https://whatisyournameinsider.com/politika/248511
  • Архив статьи № 1: https://archive.md/EttV7
  • Архив статьи № 2: https://web.archive.org/web/20220303212627/https://whatisyournameinsider.com/politika/248511

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

  • https://www.comss.ru/page.php?id=6776
  • https://ru.amnezia.org/guides/setup-wizard/


Download Article


Download Article

Creating proxy servers can increase your computer’s security as well as save a company’s bandwidth since they act as a mediator (middle-man) between your computer and the internet. Much of the time, you have to pay a subscription fee or service fee to use a proxy; however, there are proxies that are advertised as free, which probably means they don’t prioritize your safety and are thus riskier. This wikiHow will teach you how to create a proxy on Windows and Mac computers once your administrator or IT department has set up a proxy server.

  1. Image titled Create a Proxy Step 1

    1

    Open Settings. Press the Windows + I keys or open your Start menu and click the gear icon.

  2. Image titled Create a Proxy Step 2

    2

    Click Network & Internet. It’s next to an icon of a gridded globe.

    Advertisement

  3. Image titled Create a Proxy Step 3

    3

    Click Proxy. You’ll see this option at the bottom of the panel on the left side of the window next to the same gridded globe icon.

  4. Image titled Create a Proxy Step 4

    4

    Click the switch next to «Use setup script» to turn it on

    Windows Switch On

    . Doing so will enable the «Script address» text field.

  5. Image titled Create a Proxy Step 5

    5

    Enter the script address you were given and click Save. To access and use the proxy, enter the address that either your company, school, or employer gave to you, then click Save to continue. Once you close the Settings window, the changes you’ve selected should become effective immediately.

  6. Advertisement

  1. Image titled Create a Proxy Step 6

    1

    Open Settings. Press the Windows + I keys or open your Start menu and click the gear icon.

  2. Image titled Create a Proxy Step 7

    2

    Click Network & Internet. It’s next to an icon of a gridded globe.

  3. Image titled Create a Proxy Step 8

    3

    Click Proxy. You’ll see this option at the bottom of the panel on the left side of the window next to the same gridded globe icon.

  4. Image titled Create a Proxy Step 9

    4

    Click the switch next to «Use a proxy server» to turn it on

    Windows Switch On

    . Doing so will enable the «Address» and «Port» text fields.

  5. Image titled Create a Proxy Step 10

    5

    Enter an IP address and port number in the appropriate text fields then click Save. Once you’ve created your own proxy server (usually a task left to your company’s administrators or IT department), you should have at least an IP address and Port number to use. Enter that information, then click Save and your changes will be effective immediately.[1]

  6. Advertisement

  1. Image titled Create a Proxy Step 11

    1

    Open Safari. This app icon looks like a blue compass with a red dial. You can find it in your Dock or the Applications folder in Finder.

  2. Image titled Create a Proxy Step 12

    2

    Open System Preferences. With Safari in focus, click Safari from the menu at the top of your screen, then choose Preferences > Advanced.

  3. Image titled Create a Proxy Step 13

    3

    Click Change Settings. You’ll see this next to «Proxies» and another window will appear.

  4. Image titled Create a Proxy Step 14

    4

    Change the proxy settings according to the information from your network administrator. When your company, school, or employer set up a proxy, they should have given the information to you so you could use it as well.

  5. Image titled Create a Proxy Step 15

    5

    Click Ok. This will save and apply the information you entered for each instance of Safari you use.

  6. Advertisement

Add New Question

  • Question

    It says it couldn’t connect to host after running it on 000webhost.com. What now?

    Community Answer

    There are many ways to access restricted websites, most of which are discussed here. One way that is glossed over in that article and may not have been the easiest to understand, was proxies. This article will go over each type of script in more detail.

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

Video

Thanks for submitting a tip for review!

References

About This Article

Article SummaryX

1. Open Settings.
2. Click Network & Internet > Proxy.
3. Click the switch next to «Use setup script» to turn it on.

4. Enter the script address you were given and click Save.

Did this summary help you?

Thanks to all authors for creating a page that has been read 282,421 times.

Is this article up to date?


Download Article


Download Article

Creating proxy servers can increase your computer’s security as well as save a company’s bandwidth since they act as a mediator (middle-man) between your computer and the internet. Much of the time, you have to pay a subscription fee or service fee to use a proxy; however, there are proxies that are advertised as free, which probably means they don’t prioritize your safety and are thus riskier. This wikiHow will teach you how to create a proxy on Windows and Mac computers once your administrator or IT department has set up a proxy server.

  1. Image titled Create a Proxy Step 1

    1

    Open Settings. Press the Windows + I keys or open your Start menu and click the gear icon.

  2. Image titled Create a Proxy Step 2

    2

    Click Network & Internet. It’s next to an icon of a gridded globe.

    Advertisement

  3. Image titled Create a Proxy Step 3

    3

    Click Proxy. You’ll see this option at the bottom of the panel on the left side of the window next to the same gridded globe icon.

  4. Image titled Create a Proxy Step 4

    4

    Click the switch next to «Use setup script» to turn it on

    Windows Switch On

    . Doing so will enable the «Script address» text field.

  5. Image titled Create a Proxy Step 5

    5

    Enter the script address you were given and click Save. To access and use the proxy, enter the address that either your company, school, or employer gave to you, then click Save to continue. Once you close the Settings window, the changes you’ve selected should become effective immediately.

  6. Advertisement

  1. Image titled Create a Proxy Step 6

    1

    Open Settings. Press the Windows + I keys or open your Start menu and click the gear icon.

  2. Image titled Create a Proxy Step 7

    2

    Click Network & Internet. It’s next to an icon of a gridded globe.

  3. Image titled Create a Proxy Step 8

    3

    Click Proxy. You’ll see this option at the bottom of the panel on the left side of the window next to the same gridded globe icon.

  4. Image titled Create a Proxy Step 9

    4

    Click the switch next to «Use a proxy server» to turn it on

    Windows Switch On

    . Doing so will enable the «Address» and «Port» text fields.

  5. Image titled Create a Proxy Step 10

    5

    Enter an IP address and port number in the appropriate text fields then click Save. Once you’ve created your own proxy server (usually a task left to your company’s administrators or IT department), you should have at least an IP address and Port number to use. Enter that information, then click Save and your changes will be effective immediately.[1]

  6. Advertisement

  1. Image titled Create a Proxy Step 11

    1

    Open Safari. This app icon looks like a blue compass with a red dial. You can find it in your Dock or the Applications folder in Finder.

  2. Image titled Create a Proxy Step 12

    2

    Open System Preferences. With Safari in focus, click Safari from the menu at the top of your screen, then choose Preferences > Advanced.

  3. Image titled Create a Proxy Step 13

    3

    Click Change Settings. You’ll see this next to «Proxies» and another window will appear.

  4. Image titled Create a Proxy Step 14

    4

    Change the proxy settings according to the information from your network administrator. When your company, school, or employer set up a proxy, they should have given the information to you so you could use it as well.

  5. Image titled Create a Proxy Step 15

    5

    Click Ok. This will save and apply the information you entered for each instance of Safari you use.

  6. Advertisement

Add New Question

  • Question

    It says it couldn’t connect to host after running it on 000webhost.com. What now?

    Community Answer

    There are many ways to access restricted websites, most of which are discussed here. One way that is glossed over in that article and may not have been the easiest to understand, was proxies. This article will go over each type of script in more detail.

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

Video

Thanks for submitting a tip for review!

References

About This Article

Article SummaryX

1. Open Settings.
2. Click Network & Internet > Proxy.
3. Click the switch next to «Use setup script» to turn it on.

4. Enter the script address you were given and click Save.

Did this summary help you?

Thanks to all authors for creating a page that has been read 282,421 times.

Is this article up to date?

Если вам нужен прокси, то ниже вы найдёте, по моему мнению, лучший способ создания прокси. Для чего нужен прокси-сервер? Очень просто, вот несколько возможных ответов на этот вопрос:

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

2. Сокрытие своего настоящего IP-адреса. Иногда это бывает нужно для соблюдения анонимности.

3. Вы получили бан поисковой системы из-за частого обращения. Например, если Яндекс часто спрашивает, робот вы или человек.

Существует 2 варианта найти прокси-сервер: найти услугу (платную или бесплатную) или создать собственный прокси-сервер. Здесь не будем рассматривать первый вариант, т.к. нет гарантии, что на сервере не пишется лог (вероятность потери личных данных, данные банковских карт, логины и пароли). Ниже рассмотрим второй вариант: создание своего прокси-сервера.

1. Находим хостинг с поддержкой SSH

Если вы веб-мастер, то, возможно, у вас уже есть хостинг с поддержкой SSH. Если нет, то поищите в Интернете недорогой хостинг поддерживающий SSH. Встречаются хостинг-провайдеры, которые готовы предложить нужный нам хостинг за примерно за 1 доллар в месяц. Можно найти и заграничный хостинг, но это будет чуть дороже. Если поискать получше, то можно найти бесплатные варианты, но, думаю, платные будут работать надёжнее.

2. Запускаем программу PuTTY

После того как вы обзавелись хостингом с SSH, вам нужна программа PuTTY для создания локального прокси-сервера. Скачать программу бесплатно можно с официального сайта программы: www.putty.org.

3. Настраиваем программу PuTTY

После запуска программы вы увидите окно с настройками. В поле Host Name введите адрес домена или IP-адрес вашего сервера. В поле Port укажите порт, обычно это 22.

Теперь перейдите в категорию Connection->SSH->Tunnels. Здесь нужно добавить порт. Для этого в поле Source port введите порт для будущего локального прокси-сервера, например, 8888. Выберите опцию Dinamic и нажмите на кнопку Add. После этого порт появится в поле Forwarded ports — строка D8888.

Чтобы при каждом запуске не делать эту длительную процедуру, нужно сохранить текущие настройки. Для этого вернитесь в категорию Session, введите имя для своих настроек в поле Saved Sessions, например, «myhost.ru proxy» и нажмите на кнопку Save. После этого ваши настройки появятся в списке ниже. Теперь, при следующем запуске программы, вы сможете выбрать свои настройки в этом списке и нажать на кнопку Load.

4. Открываем сессию

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

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

Дальше программа попросит ваш логин и пароль в чёрном окне (при вводе пароля курсор не будет двигаться, и не будут появляться звёздочки, — это нормально).

5. Прокси-сервер готов!

После того как вы ввели логин и пароль, на экране появится информация о сервере, а ваш прокси будет доступен по адресу 127.0.0.1:8888 или localhost:8888. По окончании работы чёрное окно программы PuTTY можно закрыть, согласившись с предупреждением.

6. Настройка браузера и других программ

Чтобы воспользоваться созданным локальным прокси-сервером в браузере, нужно настроить подключение через SOCKS5 прокси-сервер, указав настройки 127.0.0.1:8888 или localhost:8888. Другие программы настраиваются аналогичным образом. Для примера рассмотрим настройку браузера Internet Explorer 10.

В меню выберите пункт «Свойства браузера».

В появившемся окне выберите закладку «Подключения» и на ней нажмите на кнопку «Настройка сети».

В окне «Настройка параметров локальной сети» поставьте галку «Использовать прокси-сервер…» (в дальнейшем, чтобы быстро включать и выключать прокси, можно просто снимать или устанавливать эту галку) и нажмите на кнопку «Дополнительно».

В окне «Параметры прокси-сервера» укажите только пункт 4. Остальные поля очистите, чтобы браузер не путался.

Теперь закройте все окна, нажимая на кнопки «ОК». Ваш браузер готов к работе через прокси.

7. Проверка

Чтобы проверить и удостовериться, что вы и в самом деле выходите в интернет через сервер, перейдите в вашем браузере на страницу одного из сервисов, которые определяют ваш IP-адрес. Например, internet.yandex.ru или более подробный сервис 2IP. Сравните IP-адрес с выключенным и включенным прокси-сервером.

153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

1

Создание прокси-сервера

21.03.2022, 15:15. Показов 8011. Ответов 21


Доброго времени суток, уважаемые форумчане!

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

То есть, чтобы было проще:
1. Запускается программа, поднимающая сервер на 127.0.0.1:5555 (как пример)
2. В игре идёт подключение к 127.0.0.1:5555
3. Программа при обнаружении того что к ней кто-то подключился — подключается к 255.522.266:2222 (пример) и начинает передавать то что передаёт игра в программу на 255.522.266:2222 а то что передаёт 255.522.266:2222 в программу передавать в игру.

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

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

Добавлено через 39 минут
И ещё, сколько в итоге понадобится сокетов? Какие функции для отправки лучше использовать в моём случае? (с приставкой WSA или без? (send / WSASend))



0



1807 / 821 / 112

Регистрация: 29.01.2013

Сообщений: 4,908

21.03.2022, 15:39

2

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



1



153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

21.03.2022, 15:40

 [ТС]

3

Цитата
Сообщение от Alli_Lupin
Посмотреть сообщение

сколько нат

Что за нат?



0



1807 / 821 / 112

Регистрация: 29.01.2013

Сообщений: 4,908

21.03.2022, 15:56

4

eXpl01TeR, что такое нат
Как это сделать на плюсах? Можно поискать примеры, или придумать самому



1



153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

21.03.2022, 20:50

 [ТС]

5

Не по теме:

Alli_Lupin, Не, друг, мне прокси свой нужен а не это.

Добавлено через 1 час 27 минут



0



Eddy_Em

Заблокирован

21.03.2022, 21:13

6

А в чем проблема-то? Что не получается?
Твоя утилита должна быть одновременно и клиентом, и сервером. Причем, для каждого ее клиента нужно делать отдельное подключение. Наиболее удобно будет создавать поток на клиента (pthreads). Настраиваешь сокет (getaddrinfo и т.п.), запускаешь (socket), настраиваешь на SO_REUSEADDR (setsockopt) и активируешь (bind), делаешь неблокирующим (ioctl) и слушаешь (listen). Дальше поллишь: как только пришел запрос на подключение следующего клиента, делаешь для него accept и с данным файловым дескриптором запускаешь новый поток. Поток коннектится к серверу (connect) и поллит (poll или select) оба конца. Как что-то с одного конца появилось, отправляешь это в другой. Т.е. нужно будет всего-то один буфер байт на 256 завести, да читать/писать.
Вуаля, у тебя появился элементарный прокси-сервер. Можно еще данные по пути как-то видоизменять, я не так давно делал штукенцию, которая из одного сокета (CAN-шина) переформатировала пакеты в другой (сокет для передачи по TCP в другую CAN-шину, фактически по «точка-точка») и обратно.

Добавлено через 1 минуту

Цитата
Сообщение от Alli_Lupin
Посмотреть сообщение

Как это сделать на плюсах?

NAT реализуется ядром операционной системы. Зачем его в userspace изобретать? Все равно будет медленней и ресурсы жрать как не в себя…



1



igorrr37

2479 / 1906 / 951

Регистрация: 21.12.2010

Сообщений: 3,474

Записей в блоге: 10

22.03.2022, 09:34

7

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

я даже с чего начать не знаю

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

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <cstdlib>
 
using tcp = boost::asio::ip::tcp;
 
 
int main()
{
    system("chcp 1251 > 0");
    std::cout << "Clientn";
    try
    {
        boost::asio::io_service io;
        tcp::socket sct(io);
        tcp::endpoint endPoint(boost::asio::ip::address::from_string("127.0.0.1"), 9090);
        boost::system::error_code ec;
        sct.connect(endPoint);
        std::cout << "Connection establishedn";
        std::string str
        {
            "www.cbr.ru  httprn"
            "GET /scripts/XML_daily.asp HTTP/1.0rn"
            "Host: www.cbr.rurn"
            "Accept: text/htmlrn"
            "Connection: closernrn"
        };
        boost::asio::write(sct, boost::asio::buffer(str));
 
        std::stringstream sst;
        boost::asio::streambuf response;
        boost::system::error_code error;
        while (boost::asio::read(sct, response, boost::asio::transfer_at_least(1), error))
        {
            sst << &response;
        }
        if (error != boost::asio::error::eof)
            throw boost::system::system_error(error);
 
        str = sst.str();
        std::cout << str;
        sct.shutdown(tcp::socket::shutdown_both);
        sct.close();
    }
    catch (std::exception const& exc)
    {
        std::cerr << "Exception: " << exc.what() << std::endl;
    }
    system("pause");
}

Прокси

Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <cstdlib>
#include <stdexcept>
#include <climits>
 
using tcp = boost::asio::ip::tcp;
 
 
int main()
{
    system("chcp 1251 > 0");
    std::cout << "Proxyn";
    try
    {
        boost::asio::io_service io;
        tcp::socket sktClient(io);
        boost::system::error_code ec;
        tcp::acceptor acc(io, tcp::endpoint(tcp::v4(), 9090));
        acc.accept(sktClient);
        std::cout << "Client acceptedn";
        boost::asio::streambuf sBuf;
        std::istream istr(&sBuf);
        boost::asio::read_until(sktClient, sBuf, "rnrn");
        std::string str, sUrl, sPort;
        istr >> sUrl >> sPort;
        istr.ignore(INT_MAX, 'n');
        tcp::resolver resolver(io);
        tcp::resolver::query query(sUrl, sPort);
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query), end;
        tcp::socket sktServer(io);
        boost::system::error_code error = boost::asio::error::host_not_found;
        while (error && endpoint_iterator != end)
        {
            sktServer.close();
            sktServer.connect(*endpoint_iterator++, error);
        }
        if (error)
            throw boost::system::system_error(error);
        std::cout << "Connected to servern";
 
        boost::asio::write(sktServer, sBuf);
 
        std::stringstream sst;
 
        while (boost::asio::read(sktServer, sBuf, boost::asio::transfer_at_least(1), error))
        {
            sst << &sBuf;
        }
        if (error != boost::asio::error::eof)
            throw boost::system::system_error(error);
 
        str = sst.str();
        //std::cout << str;
        boost::asio::write(sktClient, boost::asio::buffer(str));
 
        sktServer.shutdown(tcp::socket::shutdown_both);
        sktServer.close();
        sktClient.shutdown(tcp::socket::shutdown_both);
        sktClient.close();
        acc.close();
    }
    catch (std::exception const& exc)
    {
        std::cerr << "Exception: " << exc.what() << std::endl;
    }
    system("pause");
}



1



Eddy_Em

Заблокирован

22.03.2022, 13:36

8

Цитата
Сообщение от igorrr37
Посмотреть сообщение

под этот клиент написать прокси.

Придется от рута запускать или suid делать, т.к. 80-й порт. А выше 1024 он спокойно от непривилегированного пользователя сможет работать.



0



153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

22.03.2022, 19:51

 [ТС]

9

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

для каждого ее клиента нужно делать отдельное подключение

Клиент будет всего один, как и сервер.

igorrr37, Здесь используется библиотека Boost, я же хочу реализовать всё на голом WinAPI. Но за пример спасибо! <3



0



Eddy_Em

Заблокирован

22.03.2022, 20:58

10

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

Клиент будет всего один, как и сервер.

Тогда вообще все элементарно. Не нужно с потоками и их синхронизацией мучиться.
За буст — минус. Это дерьмо уже давным-давно deprecated. Все нужное есть либо в стандарте С++20, либо в библиотеках.



0



153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

22.03.2022, 21:03

 [ТС]

11

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

в стандарте С++20

Можно кстати ссылку где можно почитать о том что там в C++20 добавили для работы с сетями?



0



Eddy_Em

Заблокирован

22.03.2022, 21:17

12

Ну в вики же написано:

Networking extensions,[71][72] including async, basic I/O services, timers, buffers and buffer-oriented streams, sockets, and Internet protocols (blocked by executors)

Но это лучше у тех, кто на нем пишет, спрашивать. Я — сишник. О новинках С++ мне коллега рассказывает. Он уже давно смирился, что я кроме С никаких ЯП не признаю.
Прокси я делал не так давно (правда, дальше альфа-версии еще не пошел, т.к. других дел полно). Ничего там сложного…



1



2479 / 1906 / 951

Регистрация: 21.12.2010

Сообщений: 3,474

Записей в блоге: 10

23.03.2022, 09:28

13

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

либо в библиотеках

например, в асио

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

Все нужное есть либо в стандарте С++20

Так они в стандарт тот же асио и тащут. Вот,

полюбуйтесь, доктор…

. Просто названия поменяли



0



Любитель чаепитий

3734 / 1793 / 563

Регистрация: 24.08.2014

Сообщений: 5,998

Записей в блоге: 1

23.03.2022, 10:43

14

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

За буст — минус. Это дерьмо уже давным-давно deprecated.

что?

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

Все нужное есть либо в стандарте С++20, либо в библиотеках.

что?

Цитата
Сообщение от Eddy_Em
Посмотреть сообщение

Ну в вики же написано:

Deferred to a later standard

вот что там написано.



0



eXpl01TeR

153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

23.03.2022, 19:49

 [ТС]

15

Так-с. Есть текущий код:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include <WinSock2.h>
#include <WS2tcpip.h>
 
#include <iostream>
using namespace std;
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "25565"
 
 
int main()
{
    // Disable synchronization of C and C++ output streams (speeds up output)
    ios_base::sync_with_stdio(false);
 
    WSADATA wsaData;
    int iResult;
 
    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;
 
    addrinfo* result = nullptr;
    addrinfo hints {};
 
    int iSendResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
 
    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0)
    {
        cout << "Windows Sockets API initialization error" << endl;
        return 0;
    }
 
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
 
    // Resolve the server address and port
    iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
    if (iResult != 0)
    {
        cout << "GetAddrInfo failed" << endl;
        WSACleanup();
        return 0;
    }
 
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        cout << "Socket creation error" << endl;
        freeaddrinfo(result);
        WSACleanup();
        return 0;
    }
 
    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Binding error" << endl;
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Listening error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Waiting connection" << endl;
 
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET)
    {
        cout << "Accepting error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Connected" << endl;
 
    // No longer need server socket
    closesocket(ListenSocket);
 
    // Receive until the peer shuts down the connection
    do {
 
        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        if (iResult > 0)
        {
            cout << "Bytes received: " << iResult << endl;
 
            // Echo the buffer back to the sender
            iSendResult = send(ClientSocket, recvbuf, iResult, 0);
            if (iSendResult == SOCKET_ERROR)
            {
                cout << "Sending failed" << endl;
                closesocket(ClientSocket);
                WSACleanup();
                return 0;
            }
 
            cout << "Bytes send: " << iSendResult << endl;
        }
        else
        {
            if (iResult == 0)
            {
                cout << "Connection closing..." << endl;
            }
            else
            {
                cout << "Recv failed" << endl;
                closesocket(ClientSocket);
                WSACleanup();
                return 0;
            }
        }
 
    } while (iResult > 0);
 
    // shutdown the connection since we're done
    iResult = shutdown(ClientSocket, SD_SEND);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Shutdowning failed" << endl;
        closesocket(ClientSocket);
        WSACleanup();
        return 0;
    }
 
    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
    system("pause");
    return 0;
}

Как я понимаю, осталось добавить подключение к серверу, будто бы я клиент, после того, как реальный клиент ко мне подсоединился. Как правильно это сделать? Нужно будет делать в два потока, да? И вообще, приветствуются любые комментарии по поводу кода, как лучше сделать, поправить и так далее. Однако, прошу обратить внимание, я делаю всё на голом WinAPI.

Добавлено через 2 минуты
Так-же вопросик, как выяснить, какую длину буфера лучше задать? Можно ли как-то определить, какой размер буфера использует игра?

Добавлено через 6 минут
И ещё, последний вопросик, если игра использует функцию WSASend вместо обычного send и к примеру попытается отправить несколько буферов вместо одного, recv функция прочитает ведь только один? Или как это работает?

Добавлено через 5 часов 13 минут

Не по теме:

Bump >_<



0



2479 / 1906 / 951

Регистрация: 21.12.2010

Сообщений: 3,474

Записей в блоге: 10

24.03.2022, 07:41

16

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

Нужно будет делать в два потока

можно и в одном

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

какую длину буфера лучше задать

любую, например 512

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

recv функция прочитает ведь только один

прочитает все



0



eXpl01TeR

153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

24.03.2022, 12:35

 [ТС]

17

Цитата
Сообщение от igorrr37
Посмотреть сообщение

можно и в одном

Но лучше в два? Не придётся ли «костыли» писать если делать в одном?

Я нашел один пример прокси, но он не работает. Пишет GetAddrInfo failed.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
 
#include <iostream>
using namespace std;
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "22222"
 
#define TARGET_HOST "localhost"
#define TARGET_PORT "555"
 
 
addrinfo* get_addr_info(const string& host, const string& port) {
 
    addrinfo* result = nullptr;
    addrinfo hints{};
 
    int iSendResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
 
 
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
 
    // Resolve the server address and port
    int iResult = getaddrinfo(host.c_str(), port.c_str(), &hints, &result);
    if (iResult != 0)
    {
        cout << "GetAddrInfo failed" << endl;
        WSACleanup();
        return 0;
    }
    return result;
    
}
 
int main()
{
    // Disable synchronization of C and C++ output streams (speeds up output)
    ios_base::sync_with_stdio(false);
 
    WSADATA wsaData;
    int iResult;
 
    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;
    SOCKET TargetSoket = INVALID_SOCKET;
 
    auto result = get_addr_info("0.0.0.0", DEFAULT_PORT);
 
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        cout << "Socket creation error" << endl;
        freeaddrinfo(result);
        WSACleanup();
        return 0;
    }
 
    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Binding error" << endl;
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Listening error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Waiting connection" << endl;
 
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET)
    {
        cout << "Accepting error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Connected" << endl;
 
    // No longer need server socket
    closesocket(ListenSocket);
 
 
    result = get_addr_info(TARGET_HOST,TARGET_PORT);
 
    TargetSoket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
 
    iResult = connect(TargetSoket, result->ai_addr, (int)result->ai_addrlen);
 
    freeaddrinfo(result);
    if (iResult == -1)
    {
        cout << "Connect to target error" << endl;
        closesocket(TargetSoket);
        WSACleanup();
        return 0;
    }
 
    // Set to nonblocking mode
    u_long mode = 1;
    ioctlsocket(ClientSocket, FIONBIO, &mode);
    ioctlsocket(TargetSoket, FIONBIO, &mode);
 
    pollfd fds[2];
    fds[0].events = POLLIN;
    fds[0].fd = ClientSocket;
 
    fds[1].events = POLLIN;
    fds[1].fd = TargetSoket;
 
    SOCKET sockets_map[2] = { ClientSocket , TargetSoket };
    
    char buffer[DEFAULT_BUFLEN];
 
    while (true) {
    
    
        auto result = WSAPoll(fds, 2, 1000);
 
        if (!result) continue;
 
        if (result < 0) {
            break;
        }
 
 
        for (int i = 0; i < 2; ++i) {
        
            if (fds[i].revents & POLLIN) {
                fds[i].revents = 0;
                int read = recv(sockets_map[i], buffer, DEFAULT_BUFLEN, 0);
 
                if (read > 0) {
 
                    int pair_index = i ? 1 : 0;
                    int iSendResult = send(sockets_map[pair_index], buffer, iResult, 0);
 
                }
 
            }
            else {
                cout << "Disconnected or error" << endl;
                break;
 
            }
        
        
        }
 
    
    }
 
 
    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
    system("pause");
    return 0;
}



0



igorrr37

2479 / 1906 / 951

Регистрация: 21.12.2010

Сообщений: 3,474

Записей в блоге: 10

24.03.2022, 13:17

18

Цитата
Сообщение от eXpl01TeR
Посмотреть сообщение

Не придётся ли «костыли» писать

не так страшен костыль как его малюют

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <winsock2.h>
#include <ws2tcpip.h>
#include <mstcpip.h>
 
#include <iostream>
using namespace std;
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "9090"
 
#define TARGET_HOST "localhost"
#define TARGET_PORT "9091"
 
 
addrinfo* get_addr_info(const string& host, const string& port) {
 
    addrinfo* result = nullptr;
    addrinfo hints{};
    
 
    int iSendResult;
    char recvbuf[DEFAULT_BUFLEN];
    int recvbuflen = DEFAULT_BUFLEN;
 
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
 
    // Resolve the server address and port
    int iResult = getaddrinfo(host.c_str(), port.c_str(), &hints, &result);
    if (iResult != 0)
    {
        cout << "GetAddrInfo failed" << endl;
        WSACleanup();
        exit(1);
    }
    return result;
 
}
 
int main()
{
    // Disable synchronization of C and C++ output streams (speeds up output)
    ios_base::sync_with_stdio(false);
 
    WSADATA wsaData;
    int iResult;
 
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        printf("WSAStartup failed: %dn", iResult);
        return 1;
    }
 
    SOCKET ListenSocket = INVALID_SOCKET;
    SOCKET ClientSocket = INVALID_SOCKET;
    SOCKET TargetSoket = INVALID_SOCKET;
 
    auto result = get_addr_info("127.0.0.1", DEFAULT_PORT);
 
    // Create a SOCKET for connecting to server
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET)
    {
        cout << "Socket creation error" << endl;
        freeaddrinfo(result);
        WSACleanup();
        return 0;
    }
 
    // Setup the TCP listening socket
    iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Binding error" << endl;
        freeaddrinfo(result);
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    freeaddrinfo(result);
 
    iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR)
    {
        cout << "Listening error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Waiting connection" << endl;
 
    // Accept a client socket
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET)
    {
        cout << "Accepting error" << endl;
        closesocket(ListenSocket);
        WSACleanup();
        return 0;
    }
 
    cout << "Connected" << endl;
 
    // No longer need server socket
    closesocket(ListenSocket);
 
 
    result = get_addr_info(TARGET_HOST, TARGET_PORT);
 
    TargetSoket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
 
    iResult = connect(TargetSoket, result->ai_addr, (int)result->ai_addrlen);
 
    freeaddrinfo(result);
    if (iResult == -1)
    {
        cout << "Connect to target error" << endl;
        closesocket(TargetSoket);
        WSACleanup();
        return 0;
    }
 
    // Set to nonblocking mode
    u_long mode = 1;
    ioctlsocket(ClientSocket, FIONBIO, &mode);
    ioctlsocket(TargetSoket, FIONBIO, &mode);
 
    pollfd fds[2];
    fds[0].events = POLLIN;
    fds[0].fd = ClientSocket;
 
    fds[1].events = POLLIN;
    fds[1].fd = TargetSoket;
 
    SOCKET sockets_map[2] = { ClientSocket , TargetSoket };
 
    char buffer[DEFAULT_BUFLEN];
 
    while (true) {
 
 
        auto result = WSAPoll(fds, 2, 1000);
 
        if (!result) continue;
 
        if (result < 0) {
            break;
        }
 
 
        for (int i = 0; i < 2; ++i) {
 
            if (fds[i].revents & POLLIN) {
                fds[i].revents = 0;
                int read = recv(sockets_map[i], buffer, DEFAULT_BUFLEN, 0);
 
                if (read > 0) {
 
                    int pair_index = i ? 1 : 0;
                    int iSendResult = send(sockets_map[pair_index], buffer, iResult, 0);
 
                }
 
            }
            else {
                cout << "Disconnected or error" << endl;
                break;
 
            }
        }
    }
 
    // cleanup
    closesocket(ClientSocket);
    WSACleanup();
    system("pause");
    return 0;
}



1



153 / 7 / 1

Регистрация: 14.08.2019

Сообщений: 651

24.03.2022, 13:55

 [ТС]

19

igorrr37, Ошибка «GetAddrInfo failed» пропала но пишет теперь «Disconnected or error» при подключении клиента к прокси



0



2479 / 1906 / 951

Регистрация: 21.12.2010

Сообщений: 3,474

Записей в блоге: 10

24.03.2022, 14:08

20

Погадать на картах или вызвать экстрасенса? Ах, ладно.
Код клиента в студию

Миниатюры

Создание прокси-сервера
 



1



Понравилась статья? Поделить с друзьями:
  • Как написать свой телеграмм другому человеку
  • Как написать свой текстовый редактор
  • Как написать свой текст для песни
  • Как написать свой сюжет
  • Как написать свой почтовый сервер