# 데이터베이스(또는 일부)를 클라우드 데이터 처리자에게 접근 가능하게 하는 방법?

**URL:** https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915
**Category:** Self-hosting
**Created:** [4월 14, 2020, 6:48오전 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915 "2020-04-14T06:48:47Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 14, 2020, 6:48오전 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/1 "2020-04-14T06:48:47Z")

</div>

ETL 서비스인 [Stitch Data](https://www.stitchdata.com/)나 [Skyvia](https://skyvia.com/)를 사용하여 다양한 데이터 소스(제 Discourse 데이터베이스 포함)를 통합하는 데 관심이 있었지만, Skyvia 측에서 이는 불가능하다고 들었습니다:

> Skyvia는 SSH를 통해 PostgreSQL에 연결할 수 있지만, SSH 서버가 컨테이너 내부가 아니라 컨테이너 앞에 위치해 있을 경우, Docker 컨테이너 내부의 PostgreSQL에 연결하는 것은 불가능합니다.

이것은 Postgres에 연결하기 위한 [그들의 요구 사항](https://skyvia.com/resources/docs/index.html?postgresql_connections.htm)입니다.

명백한 우회 방법이 있을까요?

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [4월 14, 2020, 2:06오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/2 "2020-04-14T14:06:26Z")

</div>

Discourse 컨테이너에서 SSH를 활성화(비표준 포트 사용)한 후, 해당 포트에 대한 접속을 허용할 수 있습니다. Discourse\_docker의 samples 디렉터리에서 관련 예제를 찾을 수 있을 것 같습니다.

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 14, 2020, 2:43오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/3 "2020-04-14T14:43:05Z")

</div>

고마워, 제이. 결국 [docker-ssh](https://github.com/jeroenpeeters/docker-ssh)를 public key 인증과 함께 사용했어요. 👍

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 6:48오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/4 "2020-04-15T18:48:08Z")

</div>

어떤 핵심 개념을 놓치고 있는 것 같습니다. 커스텀 포트를 통해 ssh로 연결한 뒤 `su postgres -c 'psql discourse'`를 실행하면 아무 문제 없이 작동하기 때문입니다. 이 2단계 방식은 모두 정상적으로 작동하지만, pgAdmin과 같은 도구를 통해 직접 연결하려면 약간 다른 설정이 필요할 것 같습니다.

커스텀 포트를 노출하기 위해 사용 중인 명령은 다음과 같습니다:

```plaintext
docker run -d -p 2222:22 \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v ~/.ssh/authorized_keys:/authorized_keys \
        --name my-sshd \
        -e FILTERS={\"name\":[\"^/app$\"]} -e AUTH_MECHANISM=publicKey \
        -e AUTHORIZED_KEYS=/authorized_keys \
        jeroenpeeters/docker-ssh

```

이렇게 하면 나중에 `launcher enter app`을 실행하지 않고도 직접 다음을 수행할 수 있습니다:

```plaintext
ssh whatever@host -p 2222
su postgres -c 'psql discourse'

```

여러 가지를 시도해 보았지만 성공하지 못했습니다. `ssh whatever@host -p XXXX`를 실행하면 데이터베이스에 직접 연결될 수 있는 방법이 있을 것 같은데(아마도 pgAdmin이 기대하는 방식일 것입니다), 그러지 못하고 있습니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [4월 15, 2020, 7:29오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/5 "2020-04-15T19:29:38Z")

</div>

연결이 안 되는 건가요, 아니면 권한 문제인가요?

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 8:21오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/6 "2020-04-15T20:21:13Z")

</div>

명령줄에서 ssh를 통해 접속한 후 psql로 연결할 수 있습니다. 하지만 pgAdmin으로는 연결할 수 없습니다.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 15, 2020, 8:35오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/7 "2020-04-15T20:35:57Z")

</div>

pgAdmin을 통해 연결하려면 PostgreSQL 포트를 직접 노출해야 합니다.

`app.yml` 파일의 상단 근처에서 80번과 443번 포트가 열려 있는 것을 볼 수 있습니다. PostgreSQL용 `5432` 포트에 대한 한 줄을 더 추가할 수 있습니다.

그러나 이는 대부분 매우 나쁜 아이디어입니다. 데이터베이스가 로컬 연결만 허용하던 것에서 인터넷 전체에 노출되게 됩니다.

가끔씩 보고서를 작성할 필요가 있다면, [Data Explorer](https://meta.discourse.org/t/32566?silent=true)에서 몇 가지 CSV 파일을 다운로드하여 좋아하는 도구에 로드하는 것만으로 충분할 수 있습니다. Discourse 백업(업로드 제외)을 다운로드할 수도 있으며, 이는 표준 PostgreSQL 덤프 형식입니다. 이를 손에 넣으면 로컬 PostgreSQL 인스턴스로 복원하여 분석할 수 있습니다.

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 9:11오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/8 "2020-04-15T21:11:13Z")

</div>

감사합니다, Rafael

> [@Falco](#):
>
> `app.yml` 파일 상단 근처에서 80과 443 포트가 열려 있는 것을 볼 수 있습니다. PostgreSQL용 `5432` 포트에 대한 줄을 하나 더 추가할 수 있습니다.

이렇게 하고 컨테이너를 다시 빌드했습니다. 하지만 여전히 작동하지 않습니다 (XX.XX.XX.XX 대신 실제 IP를 사용했습니다)

 ![image](https://global.discourse-cdn.com/meta/original/3X/6/f/6f1c72440d7d18a181d90e4be04c8986de843d4b.png)

SSH 터널 탭에서는 다음과 같습니다:

 ![image](https://global.discourse-cdn.com/meta/original/3X/d/7/d758daeb2c8bcd1660bd7a63ffae412da163ab85.png)

다음과 같은 오류가 발생합니다.

 ![image](https://global.discourse-cdn.com/meta/original/3X/a/7/a7546bc832bc842703e52d80d963fdb65e14a2bf.png)

> [@Falco](#):
>
> 데이터베이스가 로컬 연결만 허용하던 것에서 인터넷 전체에 노출되도록 변경되었습니다.

이 부분에 대해선 보호 계층이 하나 줄어든다는 점은 이해하지만, 여전히 SSH 개인 키가 필요하지 않나요?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 15, 2020, 9:20오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/9 "2020-04-15T21:20:00Z")

</div>

> [@Nacho\_Caballero](#):
>
> 이 부분에 대해, 보호 계층이 하나 줄어든다는 점은 이해하지만, 여전히 SSH 개인 키가 필요하지 않나요?

`app.yml`에 `5432`를 추가하면 SSH 터널 없이 직접 노출됩니다.

pgAdmin SSH 터널에 대한 조언은 드릴 수 없습니다. 저는 사용해 본 적이 없기 때문입니다. 로컬 연결을 수신하는 포트를 기대할 것이라 가정하며, 인터넷에 노출될 필요가 없다고 생각합니다.

다음과 같이 시도해 보세요:

```plaintext
expose:
  - "80:80"
  - "443:443"
  - "5432"

```

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 9:31오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/10 "2020-04-15T21:31:06Z")

</div>

> [@Falco](#):
>
> `app.yml`에 `5432`를 추가하면 SSH 터널 없이 직접 노출됩니다.

하지만 postgres 비밀번호가 없는 이유는 슈퍼유저 권한이 필요하기 때문입니다. `pg_hba.conf` 파일에서 “local” 연결 권한이 "peer"로 설정되어 있어 UNIX 사용자를 기반으로 하며, 이를 위해 SSH 로그인이 필요하지 않나요?

이것은 작동하지 않습니다: `psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse`

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 15, 2020, 9:35오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/11 "2020-04-15T21:35:09Z")

</div>

슈퍼유저로 psql에 연결할 수 있습니다.

```plaintext
./launcher enter app
su postgres
psql

```

그리고 보고를 위해 필요한 권한을 가진 사용자를 생성합니다.

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 9:40오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/12 "2020-04-15T21:40:06Z")

</div>

네, 앱 도커 컨테이너에서 연결하는 데는 문제가 없습니다. 제 문제는 로컬 머신에서(예를 들어 pgAdmin을 사용하려고 할 때) 또는 Stitch와 같은 클라우드 데이터 프로세서에서 PostgreSQL DB에 직접 연결하는 것입니다. 이 두 가지 모두 호스트 IP 주소와 SSH 자격 증명을 요구하지만, 작동하게 만드는 데 실패했습니다(위에서 보여 드린 오류가 발생합니다).

제가 할 수 있는 유일한 방법은 [docker-ssh](https://github.com/jeroenpeeters/docker-ssh)를 사용하여 로컬 컴퓨터에서 `launcher enter app`을 실행하지 않고도 공개 키(publicKey)를 통해 앱 도커 컨테이너에 직접 접근하는 것입니다. 하지만 여전히 DB에 접근하려면 `su postgres 'psql discourse'`를 실행해야 하며, 이것이 pgAdmin/Stitch의 문제라고 추정합니다. 이 도구들은 직접 연결을 기대하기 때문입니다.

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [4월 15, 2020, 9:42오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/13 "2020-04-15T21:42:55Z")

</div>

비밀번호를 지정하여 새 PostgreSQL을 생성한 뒤, 해당 비밀번호를 서비스에 전달해 보셨나요?

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 15, 2020, 9:43오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/14 "2020-04-15T21:43:45Z")

</div>

네, 꽤 [긴 절차](https://www.stitchdata.com/docs/integrations/databases/postgresql)가 있습니다.

하지만 제 경우에도 로컬 컴퓨터에서 pgAdmin만 사용해도 동일한 문제가 발생합니다.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [4월 15, 2020, 10:50오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/15 "2020-04-15T22:50:33Z")

</div>

독립 컨테이너에서 웹과 데이터 컨테이너로 분리하는 방법([Move from standalone container to separate web and data containers](https://meta.discourse.org/t/how-to-move-from-standalone-container-to-separate-web-and-data-containers/29413))에 비밀번호 설정에 대한 설명이 있을 것 같습니다.

또한, postgres 포트는 127.0.0.1에만 바인딩할 수 있다고 생각합니다.

```plaintext
expose:
  - "80:80"
  - "443:443"
  - "127.0.0.1:5432:5432"

```

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 19, 2020, 7:06오후 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/16 "2020-04-19T19:06:22Z")

</div>

포트 노출 없이 DB에 연결할 수 있는지 확인해 보기 위해 한 발 물러서서 상황을 파악해 보려고 합니다. 😁

컨테이너에 진입하면 다음과 같은 내용이 표시됩니다:

```plaintext
# netstat -lp | grep postgres
tcp 0 0 0.0.0.0:postgresql 0.0.0.0:* LISTEN -
tcp6 0 0 [::]:postgresql [::]:* LISTEN -
unix 2 [ACC] STREAM LISTENING 263612292 - /var/run/postgresql/.s.PGSQL.5432

```

컨테이너를 종료하고 원격 서버에 있는 경우(아직 로컬 컴퓨터가 아닌 상태), 다음 명령으로 연결할 수 있지 않나요?

```plaintext
/var/discourse# psql -h localhost -d discourse -U postgres

```

문제는 비밀번호 프롬프트가 표시된다는 것입니다. postgres 사용자는 비밀번호가 없으므로, 다른 사용자를 생성하고 비밀번호를 부여해 보았습니다:

```plaintext
CREATE USER whatever_user WITH ENCRYPTED PASSWORD '<whatever password>';
GRANT CONNECT ON DATABASE discourse TO whatever_user;
GRANT USAGE ON SCHEMA public TO whatever_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whatever_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO whatever_user;

```

`pg_hba.conf` 파일에 해당 사용자를 위한 `md5` 인증 라인을 추가하고 `service postgresql restart` 명령으로 PG를 재시작했습니다.

```plaintext
# Database administrative login by Unix domain socket
local all postgres peer
local all whatever_user md5

```

그러나 원격 서버에서 연결을 시도하면 인증 실패가 발생합니다:

```plaintext
# psql -h localhost -d discourse -U whatever_user
Password for user whatever_user:
psql: FATAL: password authentication failed for user "whatever_user"
FATAL: password authentication failed for user "whatever_user"

```

무엇을 놓치고 있는 걸까요? 우선 같은 서버에서 DB에 연결할 수 있도록 하는 것이 목표입니다. 다음 단계로는 SSH 터널을 사용하여 동일한 작업을 수행할 계획이지만, 먼저 1단계부터 해결해야 할 것 같습니다. 도움이 주시면 감사하겠습니다.

---

<div class="post-metadata">

### Author: ![Nacho\_Caballero](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nacho_caballero/32/130189_2.png) [@Nacho\_Caballero](https://meta.discourse.org/u/Nacho_Caballero)
#### Post date: [4월 20, 2020, 8:20오전 UTC](https://meta.discourse.org/t/how-to-make-the-database-or-part-of-it-accessible-to-a-cloud-data-processor/147915/17 "2020-04-20T08:20:42Z")

</div>

음, 마침내 해결했어요 🎉

다음 부분:

> [@pfaffman](#):
>
> - “127.0.0.1:5432:5432”

포트가 이미 사용 중이라는 오류가 발생해서 다음과 같이 변경했어요: `- "127.0.0.1:5433:5432"`

컨테이너를 다시 빌드하고 포트가 실제로 열려 있는지 확인했습니다:

```plaintext
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
whatever_id local_discourse/app "/sbin/boot" 20 minutes ago Up 20 minutes 127.0.0.1:5433->5432/tcp app

```

이제 SSH 터널을 생성하고 비밀번호가 있는 사용자로 원격 서버에서 연결할 수 있습니다:

```plaintext
# 터널 생성 (ssh -f 옵션을 사용하면 백그라운드에서 실행할 수도 있습니다)
ssh -v -N -L 5433:localhost:5433 SERVER_IP_ADDRESS

# 다른 탭에서 연결하고 비밀번호 입력
psql -h localhost -d discourse -U whatever_user -p 5433

```

이 작업을 시도하다가 문제가 발생하면 알려주세요.
