아바타, 사이트 로고 및 인증서 오류

인스턴스 중 하나의 링크입니다:
https://discourse.mobiusnode.io

서버가 꺼져 있습니다. X-Forwarded-Proto는 제 서버 블록에 이미 포함되어 있습니다. 따라서 여러분이 공유해 주신 링크들을 기준으로 제가 아직 적용하지 않은 요소는 다음과 같습니다:

# 기본 템플릿 사용; 컨테이너 템플릿별 기능을 줄이기 위해 축소 가능:
# - "templates/cron.template.yml" # cron은 이제 기본 이미지에 포함됨
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/sshd.template.yml"
- "templates/web.template.yml"
# - "templates/web.ssl.template.yml" # 제거 - https는 외부 nginx가 처리
- "templates/web.ratelimited.template.yml"
- "templates/web.socketed.template.yml" # <-- 추가됨
# 어떤 포트를 노출할 것인가?
# expose: 전체 섹션 주석 처리

3가지 브라우저(Edge, Firefox, Chrome 모바일)에서 해당 사이트를 불러왔습니다. 익명 상태에서는 완전히 정상적인 인증서를 확인했습니다. 이 문제를 재현하기 위한 단계를 알려주실 수 있나요?

사용자로 가입하고, 가입 및 로그인 과정을 거치면 문제가 터져서 이전에 언급한 오류가 발생합니다.

알겠습니다. 지금 파이어폭스로 가짜 계정으로 가입할게요.

이메일이 제 받은 편지함으로 전혀 도착하지 않습니다. 재전송을 여러 번 시도해 보았지만 소용이 없었습니다. 계정 활성화를 수동으로 처리하고 있는 건가요?

아니요. 아마도 휴지통이나 스팸으로 갔을 겁니다. 그 부분에 대해 사용자들로부터 불만이 접수되지 않았습니다.

여기서는 지옥 같은 상황이 벌어지지 않았습니다. 잠재적인 문제 중 하나는 이메일에 여전히 http:// 링크가 포함되어 있다는 점입니다.
다만, 계정 활성화 시 https 사이트로 정상적으로 리다이렉트되었고, 여기서는 SSL 관련 오류를 확인하지 못했습니다.

그러니까 네, force_https가 활성화되어 있지 않거나, 이 문제를 일으키는 설치 환경에 매우 심각한 문제가 있는 것으로 99% 확신합니다.

서버 블록에 리디렉션이 설정되어 있어서, 거기에 어떤 링크가 표시되든 상관없습니다. 항상 https로 리디렉션됩니다.

거기서 틀렸습니다. HTTPS 강제 사용이 활성화되어 있다면, Discourse는 모든 링크를 https로 보내야 합니다. 포럼과 관련된 모든 링크는 https를 통해 로드되어야 합니다. 여전히 권장되는 방식이 아닌 이상한 방식으로 진행한다면, 그건 전적으로 본인의 책임입니다. 우리가 도울 수 있는 것은 작동하는 표준 절차까지만입니다.

나한테는 그게 별로 말이 안 돼. 논리적으로 분석해보면, 사실 나는 force-https가 하려는 것과 정확히 같은 일을 서버 블록으로 하고 있는 거잖아.

또한, force-https를 켜면 사이트가 깨지고 사용자가 인증할 수 없어요.

force_https는 단순히 리라이팅만 하는 것이 아닙니다. 내부적으로 더 많은 작업을 수행합니다. 문제를 해결하고 싶다면 이미 해결책이 제공되었습니다. 그 해결책을 거부한다면, 직접 나서서 새로운 방법을 찾아보셔도 됩니다.

그것은 불안정한 리버스 프록시 때문일 것입니다. 무엇이 문제인지 파악하고 적절하게 처리해야 합니다. 여러분이 직접 만든 솔루션에 대한 지원을 제공할 수는 없습니다.

제시된 모든 "해결책"은 제 특정 사용 사례에 맞지 않습니다:

  • 원격 서버(같은 네트워크 내) – 모든 예제가 Nginx가 Discourse와 동일한 서버에서 실행된다고 가정하는 것 같습니다. 저는 proxy_pass를 사용하여 다른 내부 IP를 호출하고 있습니다.

왜 이렇게 했을까요? 더 높은 보안과 리소스 분산 때문입니다. 컨테이너와 VM 두 가지 방식으로 서비스를 분리한 이유와 같습니다. 제안된 문서들은 모든 서비스가 동일한 서버에서 실행되는 상황을 더 선호하는 것 같습니다.

위에서 설명한 조건들이 꽤 흔할 것이라고 생각합니다. 만약 이 중 어떤 것이 proxy_pass 조건을 수용할 수 있다면, 제 설정을 그에 맞게 조정하는 데 기꺼이 응하겠습니다. ‘모든 달걀을 한 바구니에 담지 않는’ 상황을 피하려고 하는데, 단순히 그 이유만으로 "혼자 알아서 하세요"라는 일괄적인 답변을 받는 것은 다소 부당하다고 느낍니다.

proxy_pass 192.168.20.10:8080

discourse에서 192.168.20.10:8080:80를 노출합니다.

소켓 템플릿을 제거합니다.

force_https를 활성화합니다.

완료.

방금 작성하신 내용보다 훨씬 더 많은 함의가 있으며, 이것을 조사해야 합니다 — 사실 거기서 시작할 수도 있었죠. :wink:

즉각적인 질문들:

  1. app.yml에서 기본 리스닝 포트(port)를 8080으로 변경할까요?
  2. SSL 443은 어떻게 하나요? 443을 그대로 둘까요?
  3. Nginx 서버 블록의 80 포트 리다이렉트를 제거할까요?
  4. 내부 쪽의 proxy_pass만 변경하는 경우 #3이 중요할까요? 아마도 중요하지 않을 것 같은데? 8080으로 라우팅을 다시 설정하는 것뿐이니까요?
  5. 가장 큰 질문: 왜인가요? 80에서 8080으로 변경하는 것이 어떤 차이를 만들까요?
  6. 다른 모든 템플릿은 활성화된 상태로 유지할까요? socketed만 주석 처리할까요?

도와주셔서 감사합니다. 그리고 인내심을 가져주셔서 감사합니다.

그것은 본인의 취향에 따라 달라집니다. 저는 예시로 작성한 것입니다. 80 포트를 노출하도록 선택할 수도 있습니다.

로컬 네트워크에서 SSL을 활성화하는 것은 이점이나 의미가 없습니다.

그것은 존재해야 합니다.

server {
    listen 80;
    server_name discourse.example.com;
    return 301 https://example.com$request_uri;
}

그것이 정확히 일어나고 있는 일입니다. 프록시/잉레스가 수신하는 모든 요청을 포트 8080의 내부 백엔드(즉, discourse)로 전달하는 것입니다.

#1에서 답변드렸듯이 개인적인 취향입니다. 마음에 드는 포트를 자유롭게 사용하세요.

내부 서버에서는 소켓이나 SSL과 관련된 것이 전혀 필요하지 않습니다. SSL은 리버스 프록시에서 적절하게 종료(terminate)되어야 합니다.

참고: 대부분은 고객 대상 배포를 기반으로 한 개인적인 취향입니다.

네. 댓글 주셔서 감사합니다.

참고로 제 Nginx 서버 블록은 다음과 같습니다:

server {
# ssl
listen 443 ssl http2;
listen [::]:443 ssl http2;

   server_name discourse.mobiusnode.io;

   location / {
           #http trafic
           proxy_pass http://192.168.86.108;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header Host $http_host;
           proxy_http_version 1.1;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_set_header X-Forwarded-Proto https;
           proxy_set_header Upgrade $http_upgrade;
           proxy_set_header Connection "upgrade";

   }

ssl on;
ssl_certificate /path/to/certificate/domain.io/fullchain.pem; # managed by Certbot
ssl_certificate_key /path/to/certificate/domain.io/privkey.pem; # managed by Certbot

ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

add_header Strict-Transport-Security "max-age=63072000;";
ssl_stapling on;
ssl_stapling_verify on;

client_max_body_size 0;

}

server {
if ($host = discourse.mobiusnode.io) {
return 301 https://$host$request_uri;
} # managed by Certbot

listen 80;
listen [::]:80;

server_name discourse.mobiusnode.io;
return 404; # managed by Certbot

}

위 조건에서 제가 경험하는 동작은 다음과 같습니다.

app.yml 파일의 시작 부분은 다음과 같습니다:

## This is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"

## which TCP/IP ports should this container expose?
## If you want Discourse to share a port with another webserver like Apache or nginx,
## see https://meta.discourse.org/t/17247 for details
expose:
- "80:80" # http
- "443:443" # https

params:
db_default_text_search_config: "pg_catalog.english"

## Set db_shared_buffers to a max of 25% of the total memory.
## will be set automatically by bootstrap based on detected RAM, or you can override
db_shared_buffers: "1024MB"

## can improve sorting performance, but adds memory usage per-connection
#db_work_mem: "40MB"

## Which Git revision should this container use? (default: tests-passed)
#version: tests-passed

두 번째 nginx의 80번 포트에 연결하고 있으므로, http로 연결하는 것으로 인식되고 https로 인식되지 않습니다.

내부 nginx에서 X-Forwarded-Proto를 찾아 proxy_set_header X-Forwarded-Proto $thescheme;를 proxy_set_header X-Forwarded-Proto https;로 변경해 보세요.

또는 트래픽을 https로 전달하는 proxy_pass https://192.168.86.108을 사용할 수도 있습니다.

이 부분은 변경해야 합니다