У меня следующая настройка сети:
[GCP VPC]* -> [Облачный VPN-шлюз и туннель (IPSec IKEv2)] -> [локально]**
*внутренний диапазон IP: 10.0.0.0/24
**внутренний диапазон IP: 10.106.0.0/20
Локально у меня есть API (Node.js), работающий на 10.106.0.2:3000
.
Я хочу выполнить HTTP-вызовы к вышеупомянутому API из GCP.
(Весь трафик, кроме туннеля IPSec, от GCP блокируется)
А) С виртуальной машины (это работает)
Если я запущу виртуальную машину, подключенную к VPC GCP, которая «подключена» к локальной сети, я смогу:
ping 10.106.0.2 # OK
curl 10.106.0.2:3000 # OK
Следующий скрипт Node.js работает отлично:
# script.js
async function run() {
const url = 'http://10.106.0.2:3000';
try {
const response = await fetch(url);
const data = await response.text();
console.info('Response:', data);
res.status(200).send(data); // Returns the expected response from the API
} catch (error) {
console.error('Error:', error.message);
res.status(500).send(error.message);
}
}
run();
# Reaches the on-premises API and returns the expected response
$ node script.js
Б) Из облачной функции (это не работает)
Я настроил бессерверный соединитель VPC.
Затем я создал облачную функцию (gen1) с доступом к соединителю (попробовал как «Только частные диапазоны», так и «Весь трафик» в качестве настроек исходящей маршрутизации).
Функция делает то же самое, что и скрипт в виртуальной машине:
exports.helloWorld = async (req, res) => {
const url = 'http://10.106.0.2:3000';
try {
const response = await fetch(url);
const data = await response.text();
console.info('Response:', data);
res.status(200).send(data);
} catch (error) {
console.error('Error:', error.message);
res.status(500).send(error.message);
}
};
Это не работает. Я получаю следующую ошибку от функции:
{"cause":{"name":"ConnectTimeoutError","code":"UND_ERR_CONNECT_TIMEOUT","message":"Connect Timeout Error"}}
Кроме того, я попытался установить дополнительные правила брандмауэра, как описано здесь для всего входящего трафика TCP (и в частности порта 3000). Это не помогло.
Есть идеи? Я что-то пропустил?
Редактировать:
Я создал «Тест подключения», чтобы проверить соединение между моей облачной функцией и 10.106.0.2:3000
:
Редактировать 2:
Для сравнения, вот как выглядит «Тест подключения» от ВМ к той же цели (10.106.0.2:3000
):
Не уверен, что я следую, @SaiChandraGadde. Не могли бы вы уточнить? Спасибо!
По умолчанию параметр egress_setting только для частных диапазонов соединителя VPC будет маршрутизировать запросы только к диапазонам IP-адресов RFC 1918 и RFC 6598 или внутренним DNS-именам в вашу сеть VPC.
Все экземпляры соединителя получают сетевой тег «vpc-connector» и специальный тег в формате «aet-REGION-CONNECTOR_NAME». В некоторых проектах есть правило брандмауэра сети VPC, запрещающее исходящий трафик, которое может блокировать исходящий трафик из соединителя VPC, но только тогда, когда соединитель VPC маршрутизирует весь трафик через соединитель, установив для параметра egress_setting значение all-traffic.
В этом случае, чтобы разрешить исходящий трафик конкретно из соединителя, который использует настройку egress_setting для всего трафика, создайте правило брандмауэра, разрешающее исходящий трафик, с соответствующими тегами.
Вы также можете использовать Тест соединения, где вы можете указать источник и пункт назначения трафика и отслеживать, где упадет пакет.
У меня уже есть правило брандмауэра, которое разрешает выход (всем) vpc-connector
(ам). Выходная настройка для CF также уже установлена на «весь трафик».
Но упомянутый вами инструмент тестирования подключения очень полезен, спасибо. Я посмотрю, смогу ли я точно определить проблему с этим.
Поэтому изначально не было связи между 10.1.0.1
(IP-адрес в диапазоне VPC Connector) и 10.106.0.2
(целевой IP-адрес). Это произошло потому, что мне пришлось заново создать VPN-туннель (на основе политики), чтобы добавить диапазон IP-адресов соединителя (10.1.0.0/28
) в список локальных диапазонов IP-адресов. Когда я впервые создал VPN-туннель, соединителя VPC еще не существовало, следовательно, его диапазон отсутствовал. Я думал, что проблема решена... но функция Cloud по-прежнему выдает ту же ошибку :D
Можете ли вы добавить подробную информацию о настройке облачных функций с помощью VPC, прикрепить любые документы, которым вы следуете.
[Консоль]: Облачная функция -> Подключения -> Настройки исходящего трафика -> Сеть: выберите правильный соединитель из раскрывающегося списка -> Установите флажок «Направлять весь трафик через соединитель VPC». Сделанный. Тест подключения (см. редактирование исходного вопроса) показывает, что все должно быть в порядке.
Следите ли вы за этим Документом для создания Serverless VPC Access connector
и настройки своей функции для подключения к сети VPC. Если нет, можете ли вы поделиться документом, которому вы следуете? Также поделитесь, какую среду выполнения вы используете для создания облачной функции и кода?
Да, тот. Как уже упоминалось, это облачная функция Node.js 1-го поколения. Код также является частью вопроса выше.
Я попытался развернуть код, которым вы поделились, в облачных функциях, создав Serverless VPC Access connector
, следуя Документу, и успешно развернул без каких-либо ошибок. Можете ли вы убедиться, что ваше приложение прослушивает порт 3000?
Я также успешно развернул его без каких-либо ошибок. Вопрос в том, проходит ли запрос от CF к on-prem?
Чтобы решить эту проблему, мне пришлось отредактировать конфигурацию IPSec на моем локальном сервере (/etc/ipsec.conf
).
Внутренний диапазон IP-адресов бессерверного соединителя VPC (в моем случае 10.1.0.0/28
) пришлось добавить к rightsubnet
:
config setup
protostack=netkey
conn mysubnet
also=mytunnel
leftsubnet=10.106.0.0/20
rightsubnet=10.0.0.0/24,10.1.0.0/28 # <--- HERE
auto=start
conn mytunnel
left=x.x.x.x # the external IP of the on-premises server
right=y.y.y.y # the external IP of GCP's Cloud VPN Gateway
authby=secret
Теперь все работает правильно:
а) запросы от любой виртуальной машины (в 10.0.0.0/24
) и
б) запросы от любой облачной функции с прикрепленным к ней бессерверным соединителем VPC (в 10.1.0.0/28
).
добавьте статический маршрут, упомянутый в документе , внутри виртуальной машины, а не на странице маршрутов GCP.