187 lines
6.6 KiB
Markdown
187 lines
6.6 KiB
Markdown
# Объяснение работы Gateway и localAddress
|
||
|
||
## Проблема
|
||
|
||
При использовании VPN (например, WireGuard) весь интернет-трафик направляется через туннель. Однако для порт-простукивания может потребоваться использовать локальный интерфейс для обхода VPN.
|
||
|
||
## Решение: localAddress
|
||
|
||
### Как работает localAddress
|
||
|
||
`localAddress` - это параметр в Node.js Socket API, который позволяет указать локальный IP-адрес для исходящих соединений. Это заставляет операционную систему использовать конкретный сетевой интерфейс вместо маршрута по умолчанию.
|
||
|
||
### TCP соединения
|
||
|
||
```javascript
|
||
const socket = new net.Socket();
|
||
|
||
// Обычное соединение (через маршрут по умолчанию, может идти через VPN)
|
||
socket.connect(80, 'example.com');
|
||
|
||
// Соединение через конкретный локальный IP (обходит VPN)
|
||
socket.connect({
|
||
port: 80,
|
||
host: 'example.com',
|
||
localAddress: '192.168.89.1' // Ваш локальный шлюз
|
||
});
|
||
```
|
||
|
||
**Важно**: TCP сокеты НЕ поддерживают `socket.bind()`. Используйте `localAddress` в `socket.connect()`.
|
||
|
||
### UDP пакеты
|
||
|
||
```javascript
|
||
const socket = dgram.createSocket('udp4');
|
||
|
||
// Привязка к конкретному локальному IP (работает для UDP)
|
||
socket.bind(0, '192.168.89.1');
|
||
|
||
// Отправка пакета через этот интерфейс
|
||
socket.send(message, 0, message.length, 53, '8.8.8.8');
|
||
```
|
||
|
||
**Важно**: UDP сокеты поддерживают `socket.bind()` для привязки к локальному IP.
|
||
|
||
## Ваш случай с WireGuard
|
||
|
||
### Текущая ситуация:
|
||
- WireGuard активен
|
||
- Весь трафик идет через туннель
|
||
- Нужно простучать порт через локальный шлюз `192.168.89.1`
|
||
|
||
### Решение:
|
||
```javascript
|
||
// В настройках приложения указать:
|
||
{
|
||
"apiBase": "internal",
|
||
"gateway": "192.168.89.1"
|
||
}
|
||
|
||
// Или в строке цели:
|
||
"tcp:example.com:22:192.168.89.1"
|
||
```
|
||
|
||
### Что происходит:
|
||
1. Приложение получает gateway `192.168.89.1`
|
||
2. Создается сокет с `localAddress: '192.168.89.1'`
|
||
3. Операционная система направляет трафик через интерфейс с IP `192.168.89.1`
|
||
4. Трафик обходит WireGuard туннель
|
||
|
||
## Технические детали
|
||
|
||
### TCP (socket.connect с localAddress)
|
||
```javascript
|
||
socket.connect({
|
||
port: 22,
|
||
host: '192.168.1.100',
|
||
localAddress: '192.168.89.1' // Принудительно использует этот локальный IP
|
||
});
|
||
```
|
||
|
||
### UDP (socket.bind с localAddress)
|
||
```javascript
|
||
socket.bind(0, '192.168.89.1'); // Привязка к локальному IP
|
||
socket.send(message, port, host); // Отправка через этот интерфейс
|
||
```
|
||
|
||
## Проверка работы
|
||
|
||
### Логи в консоли
|
||
```
|
||
Using localAddress 192.168.89.1 to bypass VPN/tunnel
|
||
TCP connection to 192.168.1.100:22 via 192.168.89.1 successful
|
||
```
|
||
|
||
### Сетевая диагностика
|
||
```bash
|
||
# Проверить маршруты
|
||
ip route show
|
||
|
||
# Проверить интерфейсы
|
||
ip addr show
|
||
|
||
# Мониторинг трафика
|
||
tcpdump -i any host 192.168.1.100
|
||
```
|
||
|
||
## Возможные проблемы
|
||
|
||
### 1. "EADDRNOTAVAIL" ошибка
|
||
**Причина**: IP-адрес не существует на локальной машине
|
||
**Решение**: Указать корректный IP локального интерфейса
|
||
|
||
### 2. "ENETUNREACH" ошибка
|
||
**Причина**: Нет маршрута к цели через указанный интерфейс
|
||
**Решение**: Проверить сетевую конфигурацию
|
||
|
||
### 3. Трафик все еще идет через VPN
|
||
**Причина**: Неправильно указан localAddress
|
||
**Решение**:
|
||
```bash
|
||
# Найти локальный IP шлюза
|
||
ip route | grep default
|
||
# Использовать этот IP как gateway
|
||
```
|
||
|
||
## Примеры конфигурации
|
||
|
||
### Конфигурация для обхода WireGuard
|
||
```json
|
||
{
|
||
"apiBase": "internal",
|
||
"gateway": "192.168.89.1",
|
||
"inlineTargets": "tcp:external-server.com:22",
|
||
"delay": "1s"
|
||
}
|
||
```
|
||
|
||
### Смешанное использование
|
||
```
|
||
tcp:127.0.0.1:22;tcp:external-server.com:22:192.168.89.1;udp:local-dns.com:53
|
||
```
|
||
- Первая цель: через VPN (системный маршрут)
|
||
- Вторая цель: через локальный шлюз (обход VPN)
|
||
- Третья цель: через VPN (системный маршрут)
|
||
|
||
## Отладка
|
||
|
||
### Включить подробные логи
|
||
```javascript
|
||
// В настройках установить verbose: true
|
||
{
|
||
"verbose": true
|
||
}
|
||
```
|
||
|
||
### Проверить в консоли main процесса
|
||
```
|
||
Knocking TCP external-server.com:22 via 192.168.89.1
|
||
Using localAddress 192.168.89.1 to bypass VPN/tunnel
|
||
TCP connection to external-server.com:22 via 192.168.89.1 successful
|
||
```
|
||
|
||
### Мониторинг сети
|
||
```bash
|
||
# Просмотр активных соединений
|
||
netstat -an | grep 192.168.89.1
|
||
|
||
# Мониторинг трафика
|
||
sudo tcpdump -i any -n host external-server.com
|
||
```
|
||
|
||
## Безопасность
|
||
|
||
### Ограничения
|
||
- `localAddress` работает только с IP-адресами, существующими на локальной машине
|
||
- Необходимы соответствующие права для привязки к сетевым интерфейсам
|
||
- Подчиняется правилам файрвола операционной системы
|
||
|
||
### Рекомендации
|
||
- Использовать только доверенные IP-адреса
|
||
- Проверять сетевую конфигурацию перед использованием
|
||
- Логировать все попытки обхода VPN для аудита
|
||
|
||
---
|
||
|
||
**Важно**: `localAddress` - это мощный инструмент для управления сетевым трафиком, но он должен использоваться осторожно, так как может обходить сетевые политики безопасности.
|