AI Мама, я киберповстанец

AI

Команда форума
Редактор
Регистрация
23 Авг 2023
Сообщения
4,169
Реакции
0
Баллы
36
Ofline
История о том, как сисадмин борется с конторой с бюджетом в 60 млрд.
В продолжение комментария.

Ето я

Ето я

Введение​


Есть грандиозный проект, и для его существования нужны 3 вещи:
- сервера
- люди
- vpn

Компания зарубежная, и мы с удовольствием используем AWS.
Требования регуляторов привели нас к OpenVPN.
А компания любит дешёвую рабочую силу, поэтому часть сотрудников живёт в РФ.

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

client -> openvpn://bastion.example.com:1194

client -> openvpn://bastion.example.com:1194


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

КВН

КВН

Глава 1. Первые блокировки, obfs4proxy​


В какой-то момент, клиенты в РФ начали отваливаться. Анализ быстро привёл нас к пониманию, что происходит обрыв tcp соединения на этапе подключения. Но только для OpenVPN, остальной траффик ходил как положено.
Значит нам нужно замаскировать траффик, и сделать это:
- максимально удобно для сотрудников, далеко не все кулхацкеры
- безопасно для инфры, лишных дырок появиться не должно

Так у нас появился obfs4proxy c связке с Viscosity

client -> obfs://127.0.0.1:1080 -> obfs://bastion.example.com:1195 -> openvpn://bastion.example.com:1194

client -> obfs://127.0.0.1:1080 -> obfs://bastion.example.com:1195 -> openvpn://bastion.example.com:1194

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

Первые опьяняющие победы

Первые опьяняющие победы

Глава 2. Вынос части инфры из AWS.​


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

client -> obfs://127.0.0.1:1080 -> obfs://tunnel.example.com:1195 -> openvpn://bastion.example.com:1194

client -> obfs://127.0.0.1:1080 -> obfs://tunnel.example.com:1195 -> openvpn://bastion.example.com:1194

Логика была банальна:
- поставщики виртуалок не обязаны ставить ТСПУ
- у хороших вендоров есть свой канал
- серваки светятся как отечественные в россии, но имеют зарубежный IP

Такое должно прожить долго и лавочку не прикроют, верно ведь?

Всё ещё просто и весело

Всё ещё просто и весело

Глава 3. Попытка попасть в белые списки.​


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

Успешное добавление в белые списки не гарантирует работоспособность

Успешное добавление в белые списки не гарантирует работоспособность

Глава 4. Появление cloak/trojan/hysteria/vless​


В какой-то момент часть сотрудников начала жаловаться на недоступность. Снова.
Ещё одна пачка анализов и приходим к пониманию, что траффик режется. Симпомы идентичны обычному использованию OpenVPN, всё намекает на то, что протокол не столь надёжен, как хотелось бы.
Начинаем искать альтернативы. Так в течении пологода у нас заводятся shadowsocks/amnezia/ipsec/cloak/trojan/hysteria/vless/vkturnproxy.

client -> ck-client://127.0.0.1:1080 -> ck-server://tunnel.example.com:443 -> openvpn://bastion.example.com:1194

client -> ck-client://127.0.0.1:1080 -> ck-server://tunnel.example.com:443 -> openvpn://bastion.example.com:1194

Решения которые прекрасно работали для меня одного, начинают отваливаться в разных регионах страны, на разных провайдерах, в разных случаях. И в этом чёрном ящике абсолютно не понятно:
- то ли накатывают белые списки
- то ли РКН сломал часть интернета
- то ли их DPI научился детектить протокол
- то ли мы провинились
- то ли кривые руки сотрудников

Всё приходит к тому, что у нас поднята пачка методов обхода блокировок (уже 10 в документации), а на сотрудниках я тестирую.

Безмерная любовь к нашим органам

Безмерная любовь к нашим органам

Глава 5. Белые списки, поднятие серверов в РФ​


Научились обходить блокировки? Вот вам задачка со звёздочкой.
Видимо так решило моё любимое министерство цифрового отрицательного развития.
Появилась нужда резко найти IP из белых списков и использовать их. Решение пришло также быстро - обратный король мидас отечественного IT. cloud.vk.com позвляет быстро поднять VPS, а на их серваках внезапно доступны instagram/youtube/etc.

client -> ck-client://127.0.0.1:1080 -> ck-server://subway.example.com:443 -> openvpn://bastion.example.com:1194

client -> ck-client://127.0.0.1:1080 -> ck-server://subway.example.com:443 -> openvpn://bastion.example.com:1194

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

Любовь проявляется в разных формах

Любовь проявляется в разных формах

Глава 6. Отрыв IP, резервирование​


В какой-то момент работа остановилась, и пришлось вспоминать основы high availability - наличие запасного сервера.

Рака яичек им пожелал, но это почему-то не решило проблему

Рака яичек им пожелал, но это почему-то не решило проблему

Сложно сказать, что послужило причиной блокровки:
- кто-то из сотрудников сидел в max с рабочего VPN'a
- DPI действительно научился палить vless
- мои кривые руки в конфигурации сервера
- активные пробы прошлись по всем портам и нашли лишнее

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

client -> ck-client://127.0.0.1:1080 -> ck-server://{subway|underground}.example.com:443 -> openvpn://bastion.example.com:1194

client -> ck-client://127.0.0.1:1080 -> ck-server://{subway|underground}.example.com:443 -> openvpn://bastion.example.com:1194

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

Желание возлюбить

Желание возлюбить

Глава 7. Multi-hop​


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

client -> ck-client://127.0.0.1:1080 -> gost://subway.example.com:443 -> ck-server://tunnel.example.com:443 -> openvpn://bastion.example.com:1194

client -> ck-client://127.0.0.1:1080 -> gost://subway.example.com:443 -> ck-server://tunnel.example.com:443 -> openvpn://bastion.example.com:1194

Latency слегка подрос, зато наши сотрудники живут в стабильных условиях (надолго ли?).

Техносовпротивление

Техносовпротивление

Конфиги​


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

Скрытый текст

gost.yaml

Код:
services:
  - name: cloak-tcp
    addr: :443
    handler:
      type: tcp
    listener:
      type: tcp
    forwarder:
      nodes:
        - name: cloak-tcp
          addr: {{ gost_target }}:443

obfs4proxy.conf

Код:
TOR_PT_MANAGED_TRANSPORT_VER=1
TOR_PT_STATE_LOCATION=/var/lib/obfs4
TOR_PT_SERVER_TRANSPORTS=obfs4
TOR_PT_SERVER_BINDADDR=obfs4-0.0.0.0:{{ obfs4_port }}
TOR_PT_ORPORT={{ obfs4_target }}

ck-server.json

Код:
{
  "ProxyBook": {
    "openvpn": [
      "tcp",
      "{{ cloak_remote }}"
    ]
  },
  "BindAddr": [
    ":443"
  ],
  "BypassUID": [
    {{ cloak_uid }}
  ],
  "RedirAddr": "www.example.com",
  "PrivateKey": "{{ cloak_private }}"
}

ck-client.json

Код:
{
  "RemoteHost": "subway.example.com",
  "Transport": "direct",
  "ProxyMethod": "openvpn",
  "EncryptionMethod": "plain",
  "UID": "{{ cloak_uid }}",
  "PublicKey": "{{ cloak_public }}",
  "ServerName": "www.example.com",
  "NumConn": 4,
  "BrowserSig": "chrome",
  "StreamTimeout": 300
}

xray-server.json

Код:
{
  "log": {
    "loglevel": "info"
  },
  "routing": {
    "rules": [],
    "domainStrategy": "AsIs"
  },
  "inbounds": [
    {
      "listen": "0.0.0.0",
      "port": {{ xray_port }},
      "protocol": "vless",
      "tag": "vless_tls",
      "settings": {
        "clients": [
          {
            "id": "{{ xray_client }}",
            "email": "{{ xray_email }}",
            "flow": "xtls-rprx-vision"
          }
        ],
        "decryption": "none"
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "dest": "www.example.com:443",
          "xver": 0,
          "serverNames": [
            "www.example.com",
            "example.com"
          ],
          "mldsa65Seed": "",
          "privateKey": "{{ xray_private }}",
          "minClientVer": "",
          "maxClientVer": "",
          "maxTimeDiff": 0,
          "shortIds": [
            {{ xray_short }}
          ]
        }
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct"
    },
    {
      "protocol": "blackhole",
      "tag": "block"
    }
  ]
}

xray-client.json

Код:
{
    "log": {
        "level": "info"  
    },      
    "inbounds": [        
        {   
            "listen": "127.0.0.1",  
            "port": 1080,
            "protocol": "socks",    
            "settings": {
                "udp": true         
            },           
            "sniffing": {
                "enabled": true,    
                "destOverride": [   
                    "http",         
                    "tls"
                ]        
            }            
        }   
    ],      
    "outbounds": [       
        {   
            "domain_strategy": "ipv4_only",                                   
            "flow": "xtls-rprx-vision",                                       
            "packet_encoding": "xudp",                                        
            "server": "subway.example.com",                                   
            "server_port": 8443,    
            "tag": "proxy",         
            "tls": {     
                "alpn": [
                    "h2" 
                ],       
                "enabled": true,    
                "insecure": true,   
                "reality": {        
                    "enabled": true,
                    "public_key": "{{ xray_public }}", 
                    "short_id": "{{ xray_short }}"                            
                },       
                "server_name": "www.example.com",                             
                "utls": {
                    "enabled": true,
                    "fingerprint": "chrome"
                }
            },
            "type": "vless",
            "uuid": "{{ xray_uuid }}"
        },
        {
            "tag": "direct",
            "protocol": "freedom"
        },
        {
            "tag": "block",
            "protocol": "blackhole"
        }
    ]
}

ss-server.json

Код:
{
    "server": "0.0.0.0",
    "server_port": {{ ss_port }},
    "password": "{{ ss_pass }}",
    "method": "aes-256-gcm",
    "mode":"tcp_and_udp",
    "fast_open":false
}

ss-client.json

Код:
{
    "server": "tunnel.example.com",
    "server_port": {{ ss_port }},
    "password": "{{ ss_pass }}",
    "method": "aes-256-gcm",
    "local_address": "127.0.0.1",
    "local_port": 1080
}

hysteria-server.yaml

Код:
listen: :{{ hysteria_port }}

tls:
  cert: /etc/ssl/wildcard.crt
  key: /etc/ssl/wildcard.key

auth:
  type: userpass
  userpass: 
    {{ hysteria_client }}: {{ hysteria_pass }}

masquerade:
  type: proxy
  proxy:
    url: https://www.example.com
    rewriteHost: true

obfs:
  type: salamander
  salamander:
    password: {{ hysteria_obfs }}

resolver:
  type: udp
  tcp:
    addr: 8.8.8.8:53
    timeout: 4s
  udp:
    addr: 8.8.4.4:53
    timeout: 4s
  tls:
    addr: 1.1.1.1:853
    timeout: 10s
    sni: cloudflare-dns.com
    insecure: false
  https:
    addr: 1.1.1.1:443
    timeout: 10s
    sni: cloudflare-dns.com
    insecure: false

hysteria-client.yaml

Код:
server: tunnel.example.com:1984
auth: {{ hysteria_client }}: {{ hysteria_pass }}
obfs:
  type: salamander
  salamander:
	password: {{ hysteria_obfs }}
http:
  listen: 127.0.0.1:8080
socks5:
  listen: 127.0.0.1:1080

trojan-server.json

Код:
{
  "run_type": "server",
  "local_addr": "0.0.0.0",
  "local_port": {{ trojan_port }},
  "remote_addr": "{{ trojan_remote }}",
  "remote_port": 443,
  "password": ["{{ trojan_password }}"],
  "ssl": {
    "cert": "/etc/ssl/wildcard.crt",
    "key": "/etc/ssl/wildcard.key",
    "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384",
    "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
    "prefer_server_cipher": true,
    "alpn": [
      "http/1.1"
    ],
    "alpn_port_override": {
      "h2": 81
    },
    "reuse_session": true,
    "session_ticket": false,
    "session_timeout": 600,
    "plain_http_response": "",
    "curves": "",
    "dhparam": ""
  },
  "tcp": {
      "prefer_ipv4": false,
      "no_delay": true,
      "keep_alive": true,
      "reuse_port": false,
      "fast_open": false,
      "fast_open_qlen": 20
  },
  "mysql": {
      "enabled": false,
      "server_addr": "127.0.0.1",
      "server_port": 3306,
      "database": "trojan",
      "username": "trojan",
      "password": "",
      "key": "",
      "cert": "",
      "ca": ""
  }
}

trojan-client.json

Код:
{
  "run_type": "client",
  "local_addr": "127.0.0.1",
  "local_port": 1080,
  "remote_addr": "{{ trojan_remote }}",
  "remote_port": {{ trojan_port }},
  "password": [
      "{{ trojan_password }}"
  ],
  "log_level": 1,
  "ssl": {
      "verify": true,
      "verify_hostname": true,
      "cert": "",
      "cipher": "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA",
      "cipher_tls13": "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384",
      "sni": "www.example.com",
      "alpn": [
          "h2",
          "http/1.1"
      ],
      "reuse_session": true,
      "session_ticket": false,
      "curves": ""
  },
  "tcp": {
      "no_delay": true,
      "keep_alive": true,
      "reuse_port": false,
      "fast_open": false,
      "fast_open_qlen": 20
  }
}

Вывод​


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

Особое внимание:
- ТСПУ начали поставлять на сети межрегиональных провайдеров, желательно настраивать multihop, чтобы траффик из РФ выходил и шифрованным, и обфусцированным
client -> vps rf -> vps eu -> vpn
- желательно не использовать обход блокировок на мобилках одновременно с небезопасными приложениями (макс/яндекс/банки), активно сливают, можно поймать бан на следующий день
- не забываем настраивать split-tunnel, чтобы траффик для отечественных сервисов шёл внутри страны
- РКН чувствителен к портам, для белых списков только 80/443, для обхода блокировок не использовать 1337/1984/3128/8080
- РКН быстро добавляет IP в блэклист сервера за рубежом, и рубит машину в РФ, если спалит

На данный момент самым живым является схема, когда:
- есть защита от активных проб
- есть валидные tls сертификаты и настоящий веб-сервер, который отвечает
- траффик шифруется лишь 1 раз
- траффик обфусцируется и очень похож на https
- входной и выходной адреса отличаются
- есть резервирование на несколько машин внутри страны

6432e479a524278d2c899353db76ec24.png
 
Назад
Сверху Снизу
Яндекс.Метрика Рейтинг@Mail.ru