Heroku - PostgreSQL - Как удаленно подключиться в Windows

Прежде чем я получу негатив, я знаю, что есть много подобных сообщений, но я прочитал их и использовал, чтобы добраться до этого момента, но я не думаю, что они отвечают на мой вопрос.

Обзор

Я пытаюсь подключить свой тестовый сайт heroku [EDIT: удалено] к моей базе данных PostgreSQL. Раньше я пробовал MS Server, но у меня Windows, и Heroku не понравился pyodbc.

Укороченная версия

Я почти уверен, что мой PostgreSQL настроен правильно, но пытаюсь определить, правильно ли у меня указано имя хоста для URL-адреса PostgreSQL и нужно ли мне делать что-то еще в плане разрешения доступа через брандмауэр Windows.

Длинная версия

PostgreSQL


После принятого ответа Как разрешить удаленный доступ к базе данных PostgreSQL мой postgresql.conf имеет listen_addresses = '*' и порт 5432. Я поставил дополнительную строку

host all all 0.0.0.0/0 md5

на pg_hba.conf, чтобы получить следующее

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
# IPv6 local connections:
host    all             all             ::1/128                 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
host    replication     all             127.0.0.1/32            md5
host    replication     all             ::1/128                 md5
host    all         all         0.0.0.0/0       md5

Теперь я могу сделать это в командной строке

C:\etc> psql -U postgres -h 192.XXX.XX.XXX -d ProductionData

Где 192.XXX.XX.XXX — мой IPv4-адрес (можно найти в меню «Пуск» > «Изменить настройки Ethernet» > «MyCompany.local»), и все работает. Я знаю, потому что, если я отменю строку на pg_hba.conf, я получу

(venv) C:\etc> psql -U postgres -h 192.XXX.XX.XXX -d ProductionData
psql: FATAL:  no pg_hba.conf entry for host "192.XXX.XX.XXX", user "postgres", database "ProductionData", SSL off

Героку


Я понимаю, что postgres нужен URL-адрес формы

postgresql://username:password@hostname/database

or

postgresql://username:password@hostname:port/database

Я действительно не понимаю имя хоста, кроме того, что это IP-адрес сети. Я пробовал localhost и тот же IPv4-адрес, что и выше, 192.XXX.XX.XXX и 192.XXX.XX.XXX:5432.

В разделе журналов ниже есть настройка netstat, конфигурация heroku, перезапуски postgresql для каждой из этих попыток, выполненных в git bash, но я получаю следующее с двумя 192.XXX.XX.XXX в качестве тайм-аутов.

Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?

Is the server running on host "192.XXX.XX.XXX" and accepting
TCP/IP connections on port 5432?

Брандмауэр Windows


Я создал входящее правило, чтобы разрешить доступ...

Тип протокола - TCP

Местный порт - 5432

Удаленный порт — все порты

Программы - Эта программа - %ProgramFiles%\PostgreSQL\11\bin\postgres.exe

Журналы Героку


Попытка №1 - локальный хост, ошибка результата


$ pg_ctl -D "C:\Program Files\PostgreSQL\11\data" restart
waiting for server to shut down.... done
server stopped
waiting for server to start....2019-02-19 10:09:04.423 GMT [11952] LOG:  listening on IPv6 address "::", port 5432
2019-02-19 10:09:04.423 GMT [11952] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2019-02-19 10:09:04.460 GMT [11952] LOG:  redirecting log output to logging collector process
2019-02-19 10:09:04.460 GMT [11952] HINT:  Future log output will appear in directory "log".
 done
server started

$ netstat -ant | findstr 5432
  TCP    0.0.0.0:5432           0.0.0.0:0              LISTENING       InHost
  TCP    [::]:5432              [::]:0                 LISTENING       InHost

$ heroku restart -a pgtester
Restarting dynos on ? pgtester... done

$ heroku logs -t -a pgtester
...lots of stack errors...
2019-02-19T09:52:25.731597+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 437, in connect
2019-02-19T09:52:25.731599+00:00 app[web.1]: return self.dbapi.connect(*cargs, **cparams)
2019-02-19T09:52:25.731600+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
2019-02-19T09:52:25.731602+00:00 app[web.1]: conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
2019-02-19T09:52:25.731604+00:00 app[web.1]: sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
2019-02-19T09:52:25.731606+00:00 app[web.1]: Is the server running on host "localhost" (127.0.0.1) and accepting
2019-02-19T09:52:25.731607+00:00 app[web.1]: TCP/IP connections on port 5432?
2019-02-19T09:52:25.731646+00:00 app[web.1]: (Background on this error at: http://sqlalche.me/e/e3q8)

Попытка №2 - 192.XXX.XX.XXX, тайм-аут результата


$ heroku config:set DEV_DATABASE_URL=postgresql://postgres:[email protected]/ProductionData
Setting DEV_DATABASE_URL and restarting ? pgtester... done, v47
DEV_DATABASE_URL: postgresql://postgres:[email protected]/ProductionData

$ heroku restart -a pgtester
Restarting dynos on ? pgtester... done

$ netstat -ant | findstr 5432
  TCP    0.0.0.0:5432           0.0.0.0:0              LISTENING       InHost
  TCP    [::]:5432              [::]:0                 LISTENING       InHost

$ heroku logs -t -a pgtester
...lots of stack errors...
2019-02-19T10:00:57.273592+00:00 app[api]: Set DEV_DATABASE_URL config vars by user [email protected]
2019-02-19T10:00:57.273592+00:00 app[api]: Release v47 created by user [email protected]
2019-02-19T10:01:05.401378+00:00 heroku[web.1]: Starting process with command `waitress-serve --port=44666 flasky:app`
2019-02-19T10:01:05.672789+00:00 heroku[web.1]: Restarting
2019-02-19T10:01:08.193167+00:00 app[web.1]: [heroku-exec] Starting
2019-02-19T10:01:10.388293+00:00 app[web.1]: postgresql://postgres:[email protected]/ProductionData
2019-02-19T10:01:10.897113+00:00 app[web.1]: Serving on http://0.0.0.0:44666
2019-02-19T10:01:12.089984+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2019-02-19T10:01:12.196052+00:00 heroku[web.1]: Process exited with status 143
2019-02-19T10:01:12.358184+00:00 heroku[web.1]: Starting process with command `waitress-serve --port=18540 flasky:app`
2019-02-19T10:01:16.133191+00:00 app[web.1]: [heroku-exec] Starting
2019-02-19T10:01:18.520615+00:00 app[web.1]: postgresql://postgres:[email protected]/ProductionData
2019-02-19T10:01:19.161158+00:00 app[web.1]: Serving on http://0.0.0.0:18540
2019-02-19T10:01:19.687131+00:00 heroku[web.1]: State changed from starting to up
2019-02-19T10:01:33.125392+00:00 heroku[router]: at=info method=GET path="/" host=pgtester.herokuapp.com request_id=7e65dc99-b99f-4b81-8bbe-a4b98adebd91 fwd="185.16.227.58" dyno=web.1 connect=1ms service=231ms status=200 bytes=2077 protocol=https
2019-02-19T10:02:11.389923+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/" host=pgtester.herokuapp.com request_id=6837dbb0-b2e4-44ee-a67c-2f79a1c7c1b6 fwd="185.16.227.58" dyno=web.1 connect=1ms service=30000ms status=503 bytes=0 protocol=https

Попытка №3 — 192.XXX.XX.XXX:5432, тайм-аут результата


$ pg_ctl -D "C:\Program Files\PostgreSQL\11\data" restart
waiting for server to shut down.... done
server stopped
waiting for server to start....2019-02-19 10:09:04.423 GMT [11952] LOG:  listening on IPv6 address "::", port 5432
2019-02-19 10:09:04.423 GMT [11952] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2019-02-19 10:09:04.460 GMT [11952] LOG:  redirecting log output to logging collector process
2019-02-19 10:09:04.460 GMT [11952] HINT:  Future log output will appear in directory "log".
 done
server started

$ netstat -ant | findstr 5432
  TCP    0.0.0.0:5432           0.0.0.0:0              LISTENING       InHost
  TCP    [::]:5432              [::]:0                 LISTENING       InHost

$ heroku config:set DEV_DATABASE_URL=postgresql://postgres:[email protected]:5432/ProductionData
Setting DEV_DATABASE_URL and restarting ? pgtester... done, v48
DEV_DATABASE_URL: postgresql://postgres:[email protected]:5432/ProductionData

$ netstat -ant | findstr 5432
  TCP    0.0.0.0:5432           0.0.0.0:0              LISTENING       InHost
  TCP    [::]:5432              [::]:0                 LISTENING       InHost

$ heroku restart -a pgtester
Restarting dynos on ? pgtester... done

$ heroku logs -t -a pgtester
...lots of stack errors...
2019-02-19T10:11:10.352241+00:00 app[api]: Release v48 created by user [email protected]
2019-02-19T10:11:10.352241+00:00 app[api]: Set DEV_DATABASE_URL config vars by user [email protected]
2019-02-19T10:11:17.316331+00:00 heroku[web.1]: Starting process with command `waitress-serve --port=56616 flasky:app`
2019-02-19T10:11:20.998316+00:00 app[web.1]: [heroku-exec] Starting
2019-02-19T10:11:21.724624+00:00 heroku[web.1]: Restarting
2019-02-19T10:11:25.043993+00:00 app[web.1]: postgresql://postgres:[email protected]:5432/ProductionData
2019-02-19T10:11:25.797589+00:00 app[web.1]: Serving on http://0.0.0.0:56616
2019-02-19T10:11:26.872124+00:00 heroku[web.1]: Starting process with command `waitress-serve --port=51247 flasky:app`
2019-02-19T10:11:27.101119+00:00 heroku[web.1]: Stopping all processes with SIGTERM
2019-02-19T10:11:27.211928+00:00 heroku[web.1]: Process exited with status 143
2019-02-19T10:11:29.033774+00:00 app[web.1]: [heroku-exec] Starting
2019-02-19T10:11:30.261042+00:00 app[web.1]: postgresql://postgres:[email protected]:5432/ProductionData
2019-02-19T10:11:30.570976+00:00 app[web.1]: Serving on http://0.0.0.0:51247
2019-02-19T10:11:31.054334+00:00 heroku[web.1]: State changed from starting to up
2019-02-19T10:11:34.448659+00:00 heroku[router]: at=info method=GET path="/" host=pgtester.herokuapp.com request_id=7498e3a1-5a09-419b-8038-fc4bf3ddd642 fwd="185.16.227.58" dyno=web.1 connect=1ms service=170ms status=200 bytes=2077 protocol=https
...lots of stack errors...
2019-02-19T10:16:14.079101+00:00 app[web.1]: sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection timed out
2019-02-19T10:16:14.079102+00:00 app[web.1]: Is the server running on host "192.168.10.162" and accepting
2019-02-19T10:16:14.079104+00:00 app[web.1]: TCP/IP connections on port 5432?
2019-02-19T10:16:14.079144+00:00 app[web.1]: (Background on this error at: http://sqlalche.me/e/e3q8)

person Andrew Allen    schedule 19.02.2019    source источник
comment
Вы пытаетесь запустить приложение на Heroku и подключиться к базе данных Postgres, работающей локально? Могу я спросить, почему? Heroku предоставляет собственный размещенный сервис Postgres, который работает "из коробки", и если он вам не нравится по какой-то причине есть множество других варианты.   -  person Chris    schedule 19.02.2019
comment
В любом случае, вы не сможете подключить что-либо из-за пределов вашей сети к вашему локальному компьютеру, используя IP-адрес 192.x.y.z. Это сетевой локальный. Если у вас действительно есть веская причина для этого, вам понадобится статический IP-адрес или динамический домен DNS и переадресация портов или что-то подобное.   -  person Chris    schedule 19.02.2019
comment
Я пытаюсь снизить расходы, плюс мне неудобно хранить информацию о компании в облаке. Может быть, я наивен, но я думал, что будет просто отправить данные в базу данных, т.е. заменить локальный хост чем-то другим, хей, эй, вуаля, это работает. Что такое статический IP-адрес, динамический DNS-домен, переадресация портов или что-то подобное ... Я ничего не знаю об этом, как я сказал в OP. Можете ли вы указать на какие-либо хорошие источники или книги по этому поводу?   -  person Andrew Allen    schedule 19.02.2019
comment
Нетворкинг — большая тема. По сути, IP-адрес, который вы частично скрыли в своем вопросе, не виден за пределами вашей локальной сети. Относительно легко установить исходящие соединения из вашей локальной сети в облако, но гораздо сложнее пойти другим путем. Разместить приложение локально, а базу данных в облаке было бы намного проще с технической точки зрения, но если вы не хотите этого делать и вам не нужны данные в облаке, я бы рекомендовал разместить само приложение локально рядом с вашим база данных. Но ваши пользователи также должны быть локальными.   -  person Chris    schedule 19.02.2019
comment
Должен быть внешний сайт. Таким образом, веб-сайты, которые берут данные и помещают их в базу данных локально, не являются чем-то особенным, если только вы не специалист по сетевым технологиям? Я имел в виду, как вы отправляете электронное письмо, вы просто отправляете электронное письмо, и в фоновом режиме могут происходить некоторые вещи с портом, но электронное письмо доходит до указанного человека. Если дойдет до этого, я могу в конечном итоге заставить веб-сайт отправить ему данные в json по электронной почте, а затем вручную поместить их в базу данных. Я все еще хотел бы получить рекомендации по книгам по тем аспектам, которые вы упомянули. Кстати, Heroku не является местным. Его Python как сервисная (paas) платформа, заботится о python   -  person Andrew Allen    schedule 19.02.2019
comment
Это довольно просто, что касается сети, но требует некоторых базовых знаний. У меня нет книг, которые можно было бы порекомендовать, но начните с чтения о подсетях, шлюзах и NAT. В любом случае, я не вижу смысла запускать службу таким образом — если вы сделаете свою базу данных доступной для Интернета, чтобы ваше приложение на Heroku могло к ней подключиться, вы уже открываете хоть какой-то доступ к своей локальной сети. из Интернета. Если вы не заблокируете порт по IP-адресу (это невозможно с Heroku), ваша база данных по-прежнему общедоступна.   -  person Chris    schedule 19.02.2019
comment
Если ваше приложение должно работать извне (разумное требование IMO), безусловно, самое простое, что можно сделать, — это также разместить базу данных на внешнем хосте. Heroku Postgres использует SSL, поэтому соединение между приложением и база данных зашифрована. Я призываю вас потратить некоторое время на то, чтобы подумать, действительно ли вам нужно, чтобы ваша база данных размещалась внутри вашей сети. (Если вы это сделаете, переместите свое приложение туда и используйте те же сетевые навыки, о которых я упоминал, чтобы сделать ваше приложение доступным извне).   -  person Chris    schedule 19.02.2019
comment
(Я не пытаюсь снисходительно комментировать базовые знания. Работа в сети — действительно огромная и сложная тема. Я сам знаю только основы.)   -  person Chris    schedule 19.02.2019
comment
нет-нет, вы ответили на мой вопрос, не тот ответ, который я хотел, а именно тот ответ, который мне был нужен. Можете ли вы скопировать и вставить свой второй пост в ответ, чтобы я мог поставить вам зеленую галочку, а также назвать благотворительную организацию?   -  person Andrew Allen    schedule 19.02.2019


Ответы (1)


Нетворкинг — большая тема, но в целом

  • большие сети (такие как Интернет) состоят из меньших сетей (таких как ваша локальная сеть)
  • устройства в небольших сетях обычно недоступны из-за пределов этих сетей¹
  • IP-адрес, который вы частично показали, начинается с 192, и я уверен, что следующий октет будет 168, что означает, что это частная сеть и, следовательно, к ней нельзя получить доступ из Интернета (например, есть много машин с адресом 192.168.1.10 — они могут существовать в любой частной сети)
  • если вам нужно открыть что-то в вашей локальной сети, например, что-то с IP-адресом 192.168.1.10, вы должны проделать дополнительную работу²

Вот несколько вариантов:

  • Разместите свою базу данных в облаке, например. с помощью службы Heroku PostgreSQL
  • Разместите веб-службу внутри, чтобы она могла подключаться к вашей базе данных, используя свой внутренний адрес 192.168.x.y.
  • Размещайте внутри, как и в предыдущем варианте, и открывайте локальное веб-приложение в Интернете, чтобы пользователи могли получить к нему доступ из-за пределов вашей сети.
  • Арендуйте VPS, чтобы вы могли размещать за пределами своей сети, но сохраняли определенный контроль над тем, как хранятся ваши данные (и брали на себя административные издержки и ответственность, связанные с этим).

Я не советовал бы оставлять веб-приложение за пределами вашей сети, вашу базу данных внутри вашей сети и предоставлять доступ к базе данных из Интернета. В этом мало смысла, тем более что IP-адреса Heroku регулярно меняются, поэтому вы не можете легко заблокировать доступ к своему приложению. В лучшем случае у вас будет общедоступная база данных, доступная только через SSL (именно то, что могут предложить Heroku и другие провайдеры), которую вам придется администрировать самостоятельно.

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


¹Это хорошая вещь™, поскольку она обеспечивает уровень защиты от прямых атак на ваши личные устройства. Разве не было бы ужасно, если бы ваш компьютер взламывали каждый раз, когда вы ждали несколько дней, чтобы установить обновления в Windows?

²Например, можно настроить переадресацию портов на общедоступном IP-адресе вашей сети, скажем, 123.123.123.123, чтобы запросы к 123.123.123.123:1234 направлялись на определенный IP-адрес и порт в вашей внутренней сети, например 192.168.1.10:5432.

person Chris    schedule 19.02.2019