웹 서버의 모든 http 요청을 https 요청으로 다시 작성하고 싶습니다. 다음으로 시작했습니다.
서버 { 듣고 80; 위치 / { ^ (. *) https : //mysite.com$1 영구 다시 쓰기; } ...
하나의 문제는 이것이 하위 도메인 정보 (예 : node1.mysite.com/folder)를 제거한다는 것입니다. 위의 내용을 다시 작성하여 https로 모든 경로를 변경하고 하위 도메인을 유지 관리하려면 어떻게해야합니까?
웹 서버의 모든 http 요청을 https 요청으로 다시 작성하고 싶습니다. 다음으로 시작했습니다.
서버 { 듣고 80; 위치 / { ^ (. *) https : //mysite.com$1 영구 다시 쓰기; } ...
하나의 문제는 이것이 하위 도메인 정보 (예 : node1.mysite.com/folder)를 제거한다는 것입니다. 위의 내용을 다시 작성하여 https로 모든 경로를 변경하고 하위 도메인을 유지 관리하려면 어떻게해야합니까?
답변:
이 질문에 대한 첫 번째 대답은 특정 시간에 맞았지만 다른 함정으로 바뀌 었습니다. 최신 상태를 유지하려면 세금 환급을 다시 작성 하십시오.
나는 많은 SE 사용자에 의해 수정되었으므로 크레딧은 그들에게 전달되지만 더 중요한 것은 올바른 코드입니다.
server {
listen 80;
server_name my.domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name my.domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000" always;
[....]
}
$host
하는 $server_name
경우 대신 사용해야합니다 .
참고 :이 작업을 수행하는 가장 좋은 방법은 https://serverfault.com/a/401632/3641 에서 제공 되었지만 여기에서 반복됩니다.
server {
listen 80;
return 301 https://$host$request_uri;
}
가장 간단한 경우 호스트는 서비스를 보내려는 서비스로 고정됩니다. 이렇게하면 브라우저로 301 리디렉션되고 브라우저 URL이 그에 따라 업데이트됩니다.
아래는 이전 답변입니다. 정규식으로 인해 비효율적입니다. @ kmindi로 표시된 것처럼 간단한 301이 좋습니다.
nginx 0.8.39 이상을 사용하고 있으며 다음을 사용했습니다.
server {
listen 80;
rewrite ^(.*) https://$host$1 permanent;
}
클라이언트로 영구적 리디렉션을 보냅니다.
가장 좋은 유일한 방법은 HTTP 301 Moved Permanently 리디렉션을 다음과 같이 사용해야한다고 생각합니다 .
server {
listen [::]:80;
return 301 https://$host$request_uri;
}
영구적으로 이전 HTTP 301 이미 언급에 따라 평가되어야 할 정규식이 없기 때문에 리디렉션 또한 가장 효율적이다 pitfails .
새로운 HTTP 308 Moved는 영구적 으로 Request 메소드를 유지하며 주요 브라우저에서 지원합니다 . 예를 들어를 사용 308
하면 브라우저 가 리디렉션 요청 POST
에 GET
대한 요청 방법을에서 로 변경하지 못합니다 .
호스트 이름과 하위 도메인 을 유지하려면 이 방법입니다.
이것은 당신이 어떤 DNS가없는 경우 여전히 작동합니까 나는 또한 로컬로 사용하고 있습니다로. 예를 요청하고 http://192.168.0.100/index.php
으로 정확하게 리디렉션됩니다 https://192.168.0.100/index.php
.
로 설정 listen [::]:80
했기 때문에 호스트에서 사용 하므로 ipv4 소켓에도 바인딩됩니다. IPv6을 원하지 않거나 다른 곳으로 바인딩하려는 경우로 변경하십시오 .bindv6only
false
listen 80
Saif Bechan의 솔루션은 server_name
필자의 경우 localhost이지만 네트워크를 통해 도달 할 수없는 것을 사용합니다.
Michael Neale의 솔루션은 좋지만 문제에 따르면 리디렉션 301을 사용하는 더 나은 솔루션이 있습니다.)
서버 블록 내에서 다음을 수행 할 수도 있습니다.
# Force HTTPS connection. This rules is domain agnostic
if ($scheme != "https") {
rewrite ^ https://$host$uri permanent;
}
위의 내용은 항상 새로운 하위 도메인이 생성되는 경우 작동하지 않습니다. 예 : 약 30 개의 하위 도메인에 대한 AAA.example.com BBB.example.com
마지막으로 다음 작업을 수행하는 구성이 있습니다.
server {
listen 80;
server_name _;
rewrite ^ https://$host$request_uri? permanent;
}
server {
listen 443;
server_name example.com;
ssl on;
ssl_certificate /etc/ssl/certs/myssl.crt;
ssl_certificate_key /etc/ssl/private/myssl.key;
ssl_prefer_server_ciphers on;
# ...
# rest of config here
# ...
}
301 https://*/
여기의 다른 답변에서 요청을 조기에 반환 하거나 취소합니다. server_name _;
과는 $host
속임수를 썼는지 대답했다. +1
_
는 실제 도메인 으로 교체 하는 것이 좋습니다 . 예를 들어 .domain.com
두 대의 서버가 있고 nginx가 실수로 내 서버 중 하나를 기본 서버로 지정했습니다.
오래 전부터 매우 중요한 수정 사항으로 정답에 대한 의견을 게시했지만이 수정 사항을 자체 답변으로 강조 표시해야한다고 생각합니다. 안전하지 않은 HTTP 설정을하고 사용자 콘텐츠가 있거나 양식이 있거나, API를 호스팅하거나, 웹 사이트, 도구, 응용 프로그램 또는 유틸리티가 사이트와 통신하도록 구성한 경우에는 이전 답변 중 어느 것도 사용하기에 안전하지 않습니다.
POST
서버에 요청 하면 문제가 발생 합니다. 서버가 일반 30x
리디렉션으로 응답 하면 POST 컨텐츠가 손실됩니다. 무슨 일 브라우저 / 클라이언트가 SSL 요청을 업그레이드하지만 것입니다 다운 그레이드 를 POST
A를 GET
요청. POST
매개 변수가 손실되고 잘못된 요청이 서버에 이루어집니다.
해결책은 간단합니다. HTTP 1.1 307
리디렉션 을 사용해야합니다 . RFC 7231 S6.4.7에 자세히 설명되어 있습니다.
Note: This status code is similar to 302 (Found), except that it
does not allow changing the request method from POST to GET. This
specification defines no equivalent counterpart for 301 (Moved
Permanently) ([RFC7238], however, defines the status code 308
(Permanent Redirect) for this purpose).
승인 된 솔루션에서 채택한 솔루션은 307
리디렉션 코드 에 사용 하는 것입니다.
server {
listen 80;
server_name my.domain.com;
return 307 https://$server_name$request_uri;
}
server {
listen 443 ssl;
server_name my.domain.com;
# add Strict-Transport-Security to prevent man in the middle attacks
add_header Strict-Transport-Security "max-age=31536000";
[....]
}
나는 이렇게했다 :
server {
listen 80;
listen 443 ssl;
server_name domain.tld www.domain.tld;
# global HTTP handler
if ($scheme = http) {
return 301 https://www.domain.tld$request_uri;
}
# global non-WWW HTTPS handler
if ($http_host = domain.tld){
return 303 https://www.domain.tld$request_uri;
}
}
return 301 https://$host$request_uri;
포트 80의 기본 응답 인 경우 , 서버가 조만간 열린 프록시 목록에 올라 인터넷의 다른 곳으로 트래픽을 보내기 위해 남용 될 수 있습니다 [1]. 로그에 다음과 같은 메시지가 가득 차면 자신에게 발생한 일임을 알 수 있습니다.
42.232.104.114 - - [25/Mar/2018:04:50:49 +0000] "GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1" 301 185 "http://www.ioffer.com/" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Hotbar 4.1.8.0; RogueCleaner; Alexa Toolbar)"
문제는 $host
브라우저가 Host
헤더 또는 HTTP의 시작 줄에서 호스트 이름으로 보내는 모든 것을 다음과 같이 에코합니다 .
GET http://www.ioffer.com/i/new-fashion-fine-gold-bracelet-versaec-bracelet-641175733 HTTP/1.1
그 문제 때문에 여기에있는 다른 대답은 $server_name
대신 대신 사용 하는 것이 좋습니다 $host
. $server_name
항상 무엇을 평가 당신이 에 넣어 server_name
선언. 그러나 하위 도메인이 여러 개 있거나 와일드 카드를 사용하는 경우 선언 후 첫 번째 항목 $server_name
만 사용 하기 때문에 작동하지 않으며 더 중요하게 와일드 카드를 에코하지 않습니다 (확장하지 않음).server_name
보안을 유지하면서 여러 도메인을 지원하는 방법은 무엇입니까? 내 자신의 시스템에 나는함으로써이 딜레마 처리 한 첫 번째 목록 default_server
사용하지 않는 블록을 $host
다음 않는 와일드 카드 블록 목록 :
server {
listen 80 default_server;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name *.example.com;
return 301 https://$host$request_uri;
}
(두 번째 블록에 둘 이상의 도메인을 나열 할 수도 있습니다.)
이 조합을 사용하면 일치하지 않는 도메인이 하드 코드 된 곳 (항상 example.com
)으로 리디렉션 되고 자신과 일치하는 도메인이 올바른 위치로 이동합니다. 서버는 개방형 프록시로 유용하지 않으므로 문제를 일으키지 않습니다.
당신이 기분이 나쁘다면, default_server
블록을 합법적 인 도메인과 일치 시키지 않고 공격적인 것으로 만들 수 있다고 생각합니다 . . . .
[1] 기술적으로 "프록시"는 잘못된 단어입니다. 서버가 나가지 않고 클라이언트에 대한 요청을 이행하지 않고 리디렉션 만 보내지 만 올바른 단어가 무엇인지 잘 모르겠습니다. 또한 목표가 무엇인지 확실하지 않지만 로그로 노이즈를 채우고 CPU와 대역폭을 소비하므로 중지 할 수도 있습니다.
아무도 100 % 맞지 않는 것 같습니다. 포트 80 요청이 전체 웹 서버에 대해 443에 해당 하도록하려면 catch_all 이름 을 지정하기 위해 server_name 지시문이 아닌 listen 지시문 을 사용해야합니다 . 참조 https://nginx.org/en/docs/http/request_processing.html
서버 { 기본 80 듣기; 듣기 [::] : 80 기본값; 307을 반환 https : // $ host $ request_uri; }
또한 default.conf가 기존 vhost를 반환하는 문제가 발생하지 않았기 때문에 /etc/nginx/conf.d/에 이미있는 내용을 확인하십시오. nginx 문제에 대한 작업 순서는 항상 기본 파일을 이동하여 시작하여 한 줄씩 주석 처리하여 잘못된 위치를 확인합니다.