שאלה כיצד לכפות או לנתב מחדש ל- SSL ב- nginx?


יש לי דף הרשמה בתת-דומיין כגון: https://signup.example.com

זה צריך להיות נגיש רק באמצעות HTTPS, אבל אני מודאג אנשים איכשהו להיתקל בו באמצעות HTTP ולקבל 404.

אזור html / בלוק השרת ב- nginx נראה כך:

html {
  server {
    listen 443;
    server_name signup.example.com;

    ssl                        on;
    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    ssl_session_timeout 30m;

    location / {
      root /path/to/my/rails/app/public;
      index index.html;
        passenger_enabled on;
    }
  }
}

מה אני יכול להוסיף, כך שאנשים הולכים http://signup.example.com לקבל מנותב אל https://signup.example.com ? (לידיעתך יש תוסף Rails שיכול להכריח SSL אבל קיוו להימנע מכך)


210
2018-03-22 18:45




שכפול אפשרי של ב Nginx, איך אני יכול לשכתב את כל בקשות http ל- https תוך שמירה על תת תחום? - Nasreddine


תשובות:


לפי מכשולים nginx, זה קצת יותר טוב להשמיט את מיותר ללכוד, באמצעות $request_uri במקום זאת. במקרה זה, הוסף סימן שאלה כדי למנוע nginx מכפילה כל שאילתה שאילתה.

server {
    listen      80;
    server_name signup.mysite.com;
    rewrite     ^   https://$server_name$request_uri? permanent;
}

137
2018-03-22 19:22



לחלופין, על פי האתר קישרת, "טוב יותר"You return 301 http://domain.com$request_uri; - nh2
הערה אחת. $ server_name $ בוחר את המשתנה server_name הראשון. אז להיות מודע לכך אם יש לך שמות שאינם FQN בתצורה שלך - engineerDave
@ nh2 זהו מקרה נוסף של התיעוד שגוי מאז השימוש return 301... גורם "יותר מדי הפניות" שגיאה בזמן שיטת לשכתב למעשה עובד. - Mike Bethany
זה מתועד עכשיו כמו "גם BAD". @MikeBethany return 301 עושה עבודה, אלא אם כן (אני מניח) אתה מפעיל את זה גם עבור כתובות אתר נכונות, על ידי האזנה בשתי היציאות (דוגמה של config. הפעלת הבעיה: לקחת serverfault.com/a/474345/29689 's התשובה הראשונה ולהשמיט את אם). - Blaisorblade
אני תוהה מה השתנה במשך השנים והאם התשובה הזאת טובה יותר: serverfault.com/a/337893/119666 - Ryan


הדרך הטובה ביותר כפי שתואר ב את האופן הרשמי היא באמצעות return הוראה:

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

236
2017-09-03 23:50



התשובה הקצרה ביותר ועבדה בצורה מושלמת במקרה שלי - mateusz.fiolka
זה מומלץ בדרך כלל כי זה מחזיר 301 Moved Permanently (הקישורים שלך עברו לצמיתות) כמו גם כתיבה מחדש - sgb
פעולה זו אינה פועלת משום שהיא גורמת לשגיאה "יותר מדי הפניות", גם אם הגדרת proxy_set_header X-Forwarded-Proto https; - Mike Bethany
@MikeBethany אתה מגדיר listen 443; באותו בלוק? - Joe B
זו צריכה להיות התשובה המקובלת. - sjas


זוהי הדרך הנכונה והיעילה ביותר אם אתה רוצה לשמור את כל זה בלוק שרת אחד:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }
}

כל השאר מעל, באמצעות "לשכתב" או "אם ssl_protocol" וכו 'הוא איטי יותר ויותר.

הנה הוא זהה, אבל אפילו יותר יעיל, על ידי הפעלת רק לשכתב על פרוטוקול http הוא נמנע צורך לבדוק את המשתנה סכמה $ על כל בקשה. אבל ברצינות, זה דבר כל כך קטין שאתה לא צריך להפריד ביניהם.

server {
    listen   80;
    listen   [::]:80;

    server_name www.example.com;

    return 301 https://$server_name$request_uri;
}
server {
    listen   443 default_server ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;
}

108
2018-01-31 20:43



נהדר, איזה פחדן הצביע תשובה זו למטה בלי לומר למה, למרות התשובה הזו נכונה. אולי עוד אחד מאותם פולחן "רעים". אם אתה טורח לקרוא את התיעוד Nginx על אם, אתה יודע כי IfIsNOTEvil, רק CERTAIN משתמש בו בהקשר {} הקשר, אף אחד מהם אנו עושים כאן. התשובה שלי היא בהחלט הדרך הנכונה לעשות דברים! - DELETEDACC
אני לא למטה להצביע זה, אבל אני רוצה לציין כי ברירת המחדל השתנתה ל 'default_server' בגירסאות האחרונות. - spuder
הפתרון הראשון לא יכול להיות היעיל ביותר, אם השני הוא אפילו יותר יעיל. ואתה אפילו תיאר, למה אתה לא צריך להשתמש אם יש: "זה ימנע צורך לבדוק את המשתנה סכמה $ על כל בקשה". הנקודה של שימוש לא אם היא לא רק על הביצועים, אלא גם על להיות הצהרתי, ולא חובה. - pepkin88
+1 עבור אם ($ schem = http) - Fernando Kosh
כדאי להשתמש במארח $ כאן, כפי שצוין בתשובות האחרות. - Artem Russakovskii


אם אתה משתמש בהגדרת שרת HTTP ו- HTTPS כפולה חדשה, תוכל להשתמש בפריטים הבאים:

server {
    listen   80;
    listen   [::]:80;
    listen   443 default ssl;

    server_name www.example.com;

    ssl_certificate        /path/to/my/cert;
    ssl_certificate_key  /path/to/my/key;

    if ($ssl_protocol = "") {
       rewrite ^   https://$server_name$request_uri? permanent;
    }
}

נראה שזה עובד בשבילי ואינו גורם לניתוב מחדש.

ערוך:

הוחלף:

rewrite ^/(.*) https://$server_name/$1 permanent;

עם קו הכתיבה מחדש של פרטיק.


56
2017-08-08 11:12



@ DavidPashley הפתרון שלך עבד כמו קסם בשבילי. תודה - Jayesh Gopalan
If you are using the new dual HTTP and HTTPS server definition אז אתה צריך להפריד אותו. - VBart
אלגנטי ועובד מושלם! - jipipayo
זה היה הפתרון היחיד שעבד בשבילי עם התצורה Lginvel / Homestead Nginx. - Jared Eitnier
גם קו לשכתב צריך להיות return 301 https://$server_name$request_uri; שכן זו השיטה המועדפת. - Jared Eitnier


גרסה אחרת, השומרת על המארח: כותרת הבקשה ומלווה את הדוגמה "GOOD" מכשולים nginxYou

server {
    listen   10.0.0.134:80 default_server;

    server_name  site1;
    server_name  site2;
    server_name  10.0.0.134;

    return 301 https://$host$request_uri;
}

הנה התוצאות. שים לב כי השימוש $server_name במקום $host תמיד יפנה אל https://site1.

# curl -Is http://site1/ | grep Location
Location: https://site1/

# curl -Is http://site2/ | grep Location
Location: https://site2/


# curl -Is http://site1/foo/bar | grep Location
Location: https://site1/foo/bar

# curl -Is http://site1/foo/bar?baz=qux | grep Location
Location: https://site1/foo/bar?baz=qux

27
2018-04-11 12:20



Note that using $server_name instead of $host would always redirect to https://site1 זה לא מה $request_uri בשביל? - Jürgen Paul
$request_uri אינו מכיל שם מארח או שם תחום. במילים אחרות, זה תמיד מתחיל עם תו "/". - Peter
התשובה הטובה ביותר על ידי רחוק. - Ashesh
אני לא בטוח למה התשובה הזאת כל כך נמוכה בקולות. זה רק אחד שווה להשתמש. - zopieux
לא יכול להאמין שאנשים רבים משתמשים $ server_name זו הדרך הנכונה לעשות את זה - Greg Ennis


הקפד להגדיר 'מאובטח' על כל העוגיות, או אחר הם יישלחו על בקשת HTTP ויכול להיות שנתפס על ידי כלי כמו Firesheep.


3
2018-03-23 00:40





server {
    listen x.x.x.x:80;

    server_name domain.tld;
    server_name www.domian.tld;
    server_name ipv4.domain.tld;

    rewrite     ^   https://$server_name$request_uri? permanent;
}

זה עובד טוב יותר אני חושב. x.x.x.x מתייחס לכתובת השרת שלך. אם אתה עובד עם Plesk 12, אתה יכול לעשות זאת על ידי שינוי "nginx.conf" הקובץ בספרייה "/var/www/vhosts/system/domain.tld/conf" עבור התחום הרצוי. אל תשכח להפעיל מחדש את שירות nginx לאחר שמירת התצורה.


1
2017-08-23 19:40



rewrite ^ https://$host$request_uri? permanent;  יהיה פתרון טוב יותר כפי שאולי יש מספר שמות שרת על vhost


אני חושב שזה הפתרון הפשוט ביותר. כופה הן תנועה שאינה HTTPS והן תנועה שאינה WWW ל- HTTPS ו- www בלבד.

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;
    }
}

עריכה - אפריל 2018: פתרון w / o IF ניתן למצוא בהודעה שלי כאן: https://stackoverflow.com/a/36777526/6076984


0
2018-04-21 18:30



האם לא התנאים נחשבים רעים ולא יעילים בעולם nginx? - PKHunter
כן הם, באופן כללי. אבל בשביל הבדיקות הפשוטות האלה אני מניחה שלא. יש לי קובץ התצורה הנכון אשר כרוך יותר בכתב קוד אבל, אבל נמנע IF לחלוטין. - stamster
Google ממליצה להשתמש 301 במקום 303. מקור: support.google.com/webmasters/answer/6073543?hl=iw - dylanh724
@ DylanHunt - עזבתי 303 רק לבדיקה, לקחת פתק כי המטפל הראשון היה מוגדר 301, רק 2 שכחתי לשנות :) כמו כן, פתרון w / o IF: stackoverflow.com/a/36777526/6076984 - stamster