Як Spotify може допомогти у вивченні демонів, RFC, мереж та просування опенсорсу. Або, що буває, якщо заплатити не виходить, а деякі преміумні плюшки дуже хочеться.
Початок
На третій день було помічено, що Спотифай видає рекламу виходячи з країни ip-адреси. Там було помічено, що у деяких країнах рекламу не завезли зовсім. Наприклад, у РБ. І відразу дозрів «геніальний» план з відключення реклами в не преміумному акаунті.
Трохи про Spotify
Взагалі кажучи, у Спотифа дивна політика. Нашому братові доводиться неабияк перекручуватися, щоб купити преміум: змінювати локацію в профілі на заморську, шукати відповідний гіфткард, який можна оплатити тільки paypal-ом, який останнім часом дивує і хоче купу документів. Загалом теж пригода, але іншого порядку. Хоча більшість цим займається заради мобільної версії, мене така не цікавить. Тому все нижченаведене допоможе тільки у випадку з десктопною версією. Більше того, ніякого розширення функцій не буде. Лише відрізання деяких зайвих.
А що складного?
І я так думав, прописуючи дані socks-proxy у конфізі Spotify. Проблема виявилася в тому, що у них не працює аутентифікація в socks за логіном та паролем. Плюс розробники регулярно щось крутять довкола проксика: то дозволяючи, то забороняючи, то ламаючи його, що породжує цілі полотнища обговорень на оф.сайті.
Було вирішено не покладатися на нестабільні функції та знайти щось надійніше та цікавіше.
Десь тут читач має спитати: а чого б не взяти ssh
з ключиком -D
і справа з кінцем? І, загалом, матиме рацію. Але, по-перше, це ще потрібно демонізувати і подружити з autossh, щоб не думати про конекти, що рвуться. І по-друге: це надто просто і нудно.
По порядку
Як завжди, давайте підемо зліва направо, зверху вниз і опишемо все, що нам потрібно для реалізації нашої «простої» витівки.
Для початку потрібен проксі
І одразу багато альтернатив:
- можна просто піти та взяти з відкритих проксилістів. Дешево (точніше задарма), але абсолютно ненадійно і час життя таких проксиків прагне нуля. Тому треба було б знайти/написати парсер проксі списків, фільтрувати їх за потрібним типом і країною і питання підстановки знайденого проксі в Spotify залишається відкритим (ну, хіба що, через
HTTP_PROXY
передавати і кастомну обгортку для бінарника робити, щоб решту всіх трафік туди ж не відправити). - Можна купити аналогічний проксі та позбавити себе більшості вищеописаних проблем. Але за ціни проксі можна відразу купити преміум на Спотифай, а це не спортивно в рамках вихідного завдання.
- Підняти свій. Як ви, мабуть, здогадалися це наш вибір.
Чисто випадково може виявитися, що у вас є один із сервером у РБ чи іншій невеликій країні. Цим потрібно користуватися та розкочувати на ньому бажаний проксик. Особливі ж поціновувачі, можуть задовольнятися другом з роутем на
Отже, наші варіанти: Squid - не надихає, та й не хочеться HTTP-проксик, цього протоколу і так багато навколо. А в області SOCKS нічого розумного крім
Манула по установці та налаштуванню Данте не чекайте. Він client pass
, socks pass
, правильно прописати інтерфейси та не забути додати socksmethod: username
. У такому вигляді для автентифікації логопас братиметься з користувачів системи. А частина про безпеку: заборона доступу до локалхосту, обмеження по користувачах та інше – це вже суто індивідуально залежно від особистої параної.
Розгорнути проксі обличчям у мережу
Вистава у двох актах.
акт перший
З проксі розібралися, тепер треба отримати до нього доступ із глобальної павутини. Якщо у вас є машинка з білим IP у потрібній країні, то можете сміливо пропускати цей пункт. У нас же такої немає (ми, як говорилося вище, хостимось у друзів вдома) і найближчий білий айпі десь у Німеччині, тому вивчатимемо мережі.
Так уважний читач знову запитуватиме: а чого б вам не взяти існуючий сервіс типу
Завдання: є проксі десь далеко за NAT, треба його повісити на один з портів VPS, що має білий IP і розташованої на краю світу.
Логічно припустити, що це вирішується або прокиданням порту (який реалізується через вищезгаданий ssh
), або об'єднанням залізниць у віртуальну мережу через VPN. З ssh
працювати вміємо, autossh
брати нудно, тому візьмемо OpenVPN.
DigitalOcean має systemd
. Достатньо покласти його (конфіг) у /etc/openvpn/client/
і не забути змінити розширення на .conf
. Після цього смикнути службу [email protected]
, не забути зробити для неї enable
і радіти з того, що все полетіло.
Звичайно ж, потрібно відключити будь-яке перенаправлення трафіку в свіжостворений VPN, адже ми не хочемо порізати швидкість на клієнській машині за рахунок перегону трафіку через півкулі.
І так, потрібно прописати статичну IP-адресу на VPN-сервері для нашого клієнта. Це знадобиться трохи далі за розповіддю. Для цього потрібно увімкнути ifconfig-pool-persist
, поредагувати ipp.txt
, що йде в комплекті з OpenVPN і включити client-config-dir, плюс редагувати конфіг потрібного клієнта, додавши ifconfig-push
з правильною маскою та бажаною IP-адресою.
акт другий
Тепер у нас у «мережі» є машина, яка повернута обличчям до інтернету і їй можна скористатися з корисливою метою. Зокрема, перенаправити частину трафіку через неї.
Отже, нове завдання: потрібно загорнути трафік, що прилітає на один із портів VPS з білим айпі так, щоб цей трафік відлетів у свіжо підключену віртуальну мережу і відповідь змогла звідти повернутися.
Спосіб вирішення: звичайно ж iptables
! Коли ще буде така чудова можливість з ним повправлятися?
Потрібна конфігурація знаходиться незабаром, за трійку годин, сотню лайливих слів і жменю витрачених нервів, бо дебаг мереж — це дуже специфічна процедура.
По-перше, потрібно включити перенаправлення трафіку в ядрі. Ця штука називається ipv4.ip_forward
і включається трохи по-різному залежно від ОС та мережного менеджера.
По-друге, потрібно вибрати порт, на VPS і загорнути весь трафік, що йде на нього у віртуальну підмережу. Це можна зробити, наприклад, ось так:
iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 8080 -j DNAT --to-destination 10.8.0.2:8080
Тут ми перенаправляємо весь TCP-трафік, що прийшов на порт 8080 зовнішнього інтерфейсу на машину з айпі 10.8.0.2 і порт 8080.
Тим, хто хоче брудних подробиць роботи netfilter
, iptables
і взагалі роутингу, абсолютно необхідно споглядати
Отже, тепер у нас пакети відлітають у віртуальну підмережу і там і залишаються. Точніше відповідь від socks-проксі летить назад через дефолтний gateway на машині з Dante і адресат його дропає, бо в мережах не прийнято відправляти запит на один IP, а отримувати відповідь з іншого. Тому потрібно чаклувати далі.
Отже, тепер потрібно перенаправити всі пакети від проксика назад у віртуальну підмережу у бік VPS із білим IP. Тут ситуація трохи гірша, бо просто iptables
нам не вистачить, бо якщо ми поправимо адресу призначення до роутингу (PREROUTING
), то наш пакет в інтернет не відлетить, а якщо не поправимо - пакет піде в default gateway
. Отже, треба робити таке: згадати про ланцюжок mangle
, щоб помітить пакети через iptables
і загорнути їх у кастомну таблицю маршрутизації, яка відправить їх куди слід.
Сказано зроблено:
iptables -t mangle -A OUTPUT -p tcp --sport 8080 -j MARK --set-mark 0x80
ip rule add fwmark 0x80 table 80
ip route add default via 10.8.0.1 dev tun0 table 80
Беремо вихідний трафік, маркуємо все, що летить з порту, на якому сидить проксі (8080 у нашому випадку), перенаправляємо весь помічений трафік до таблиці маршрутизації з номером 80 (загалом номер ні від чого не залежить, просто так захотілося) і додаємо єдине правило , За яким усі пакети, що потрапили в цю таблицю відлітають у підмережу VPN.
Чудово! Тепер пакети відлітають назад у бік VPS… та вмирають там. Тому що VPS не в курсі, що з ними робити. Тому, якщо не морочитися, можна просто взяти і перенаправити весь трафік, що прилітають з віртуальної підмережі назад в інтернет:
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j SNAT --to-source 172.42.1.10
Тут все, що прилітає з підмережі 10.8.0.0 з маскою 255.255.255.000, загортається в source-NAT і летить у дефолтний інтерфейс, який повернутий в інтернет. Важливо, що ця штука буде працювати тільки якщо ми прозоро прокидаємо порт, тобто вхідний порт на VPS збігається з портом нашого проксі. Інакше треба буде страждати трохи більше.
Десь зараз все має почати працювати. І залишиться зовсім небагато: не забути зробити так, щоб усі конфіги iptables
и route
не довбали після рестарту. Для iptables
є спеціальні файлики типу /etc/iptables/rules.v4
(У випадку Ubuntu), а для роутів все трохи складніше. Я їх заштовхав у up/down
скрипти OpenVPN-а, хоча, здається мені, можна було й пристойніше зробити.
Загорнути трафік від програми в proxy
Отже, у нас є проксі з автентифікацією в потрібній країні, доступний за статичним білим IP-адресою. Залишилося ним скористатися та перенаправити туди трафік від Spotify. Але є нюанс, як говорилося вище, логін-пароль для проксику в Спотифаї не працює, тому шукатимемо як викрутитися.
Для початку, згадаємо про
Але радість буде недовгою, бо виявиться, що потрібно включити режим дебага і кастомні розширень ядра в MacOS, запиляти нескладний конфіг і зрозуміти, що у цієї тулзи так само проблема, що і у Spotify: вона не може пройти аутентифікацію по логіну-паролю на socks-proxy.
Десь тут час психанути і таки купити преміум ... але ні! Спробуємо попросити відремонтувати, це ж опенсорс! Робимо
Знов засмутимося. Але потім згадаємо молодість і Сі, включимо дебаг режим у Dante, покопаємось у сотні кілобайт ліг, сходимо в
Автоматизуй це
Якщо Proximac заробив, його потрібно демонізувати і забути про нього. Для цього підходить ціла система ініціалізації, яка є в MacOS, а саме
Швидко знаходимо systemd
і тут майже совок і xml
. Ніяких тобі красивих конфігів, жодних команд вигляду status
, restart
, daemon-reload
. Тільки хардкор виду start-stop
, list-grep
, unload-load
і ще багато дивно. Перемагаючи все це пишемо plist
, завантажуємо. Не працює. Вивчаємо спосіб дебагу демона, дебажимо, розуміємо що там ENV
навіть PATH
не завезли нормальний, лаємося, завозимо (додаючи /sbin
и /usr/local/bin
) і нарешті радіємо автостарту та стабільній роботі.
Видихаємо
Що зрештою? Тиждень пригод, наколінний зоопарк із сервісів, який дорогий серцю і робить те, що від нього вимагається. Небагато знань у сумнівних технічних областях, крапелька опенсорсу та посмішка на обличчі від думки «Я зроблю!»
PS: це не заклик до бойкоту капіталістів, до економії на сірниках або до тотальної хитроспості, а лише вказівку на можливості дослідження та розвитку там, де їх, загалом, не очікуєш.
Джерело: habr.com