ค้นหาเว็บไซต์

แก้ไขข้อผิดพลาด “คำขอ HTTP ธรรมดาถูกส่งไปยังพอร์ต HTTPS” ใน Nginx


ในบทความนี้ เราจะแสดงวิธีแก้ปัญหา “400 คำขอไม่ถูกต้อง: คำขอ HTTP ธรรมดาถูกส่งไปยังพอร์ต HTTPS” ในเซิร์ฟเวอร์ Nginx HTTP โดยปกติข้อผิดพลาดนี้จะเกิดขึ้นเมื่อคุณพยายามกำหนดค่า Nginx ให้จัดการทั้งคำขอ HTTP และ HTTPS

สำหรับวัตถุประสงค์ของคู่มือนี้ เรากำลังพิจารณาสถานการณ์ที่ nginx ให้บริการเว็บไซต์หลายแห่งที่ใช้งานผ่านบล็อกเซิร์ฟเวอร์ (หรือโฮสต์เสมือนใน Apache) มีเพียงเว็บไซต์เดียวเท่านั้นที่ใช้ SSL และส่วนที่เหลือไม่รองรับ

อ่านเพิ่มเติม: สุดยอดคู่มือในการรักษาความปลอดภัย เสริมความแข็งแกร่ง และปรับปรุงประสิทธิภาพของ Nginx

นอกจากนี้เรายังจะพิจารณาตัวอย่างการกำหนดค่า SSL ด้านล่าง (เราได้เปลี่ยนชื่อโดเมนจริงด้วยเหตุผลด้านความปลอดภัย) ซึ่งบอกให้ nginx ฟังทั้งพอร์ต 80 และ 443 และคำขอทั้งหมดบน HTTP ควรเปลี่ยนเส้นทางไปยัง HTTPS ตามค่าเริ่มต้น

การกำหนดค่าตัวอย่าง Nginx

server{
        listen 80;
        server_name example.com www.example.com;
        return 301 https://www.example.com$request_uri;
}
server {
        listen 443 ssl http2;
        server_name example.com www.example.com;

        root   /var/www/html/example.com/;
        index index.php index.html index.htm;

        #charset koi8-r;
        access_log /var/log/nginx/example.com/example.com_access_log;
        error_log   /var/log/nginx/example.com/example.com_error_log   error;

        # SSL/TLS configs
        ssl on;
        ssl_certificate /etc/ssl/certs/example_com_cert_chain.crt;
        ssl_certificate_key /etc/ssl/private/example_com.key;

        include /etc/nginx/ssl.d/ssl.conf;

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
                root   /var/www/html/example.com/;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {

                root   /var/www/html/example.com/;
                fastcgi_pass   127.0.0.1:9001;
                #fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
                fastcgi_index  index.php;
                fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                include         fastcgi_params;
                include /etc/nginx/fastcgi_params;

        }
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
}

เมื่อใช้การกำหนดค่าข้างต้น เมื่อไคลเอนต์พยายามเข้าถึงไซต์ของคุณผ่านพอร์ต 80 เช่น http://example.com ข้อผิดพลาดที่เป็นปัญหาจะแสดงดังต่อไปนี้ ภาพหน้าจอ

คุณพบข้อผิดพลาดนี้เนื่องจากทุกครั้งที่ไคลเอนต์พยายามเข้าถึงไซต์ของคุณผ่าน HTTP คำขอจะถูกเปลี่ยนเส้นทางไปยัง HTTPS เป็นเพราะ nginx คาดว่า SSL จะใช้ในการทำธุรกรรม แต่คำขอดั้งเดิม t (รับผ่านพอร์ต 80) นั้นเป็น HTTP ธรรมดา จึงบ่นว่ามีข้อผิดพลาด

ในทางกลับกัน หากลูกค้าใช้ https://example.com พวกเขาจะไม่พบข้อผิดพลาดข้างต้น นอกจากนี้ หากคุณมีเว็บไซต์อื่นที่กำหนดค่าไม่ให้ใช้ SSL nginx จะพยายามใช้ HTTPS เป็นค่าเริ่มต้นสำหรับเว็บไซต์เหล่านั้นซึ่งส่งผลให้เกิดข้อผิดพลาดข้างต้น

หากต้องการแก้ไขข้อผิดพลาดนี้ ให้ใส่เครื่องหมายความคิดเห็นในบรรทัดด้านล่างในการกำหนดค่าของคุณหรือตั้งค่าเป็นปิด

#ssl on 
OR
ssl off

บันทึกและปิดไฟล์ จากนั้นรีสตาร์ทบริการ nginx

systemctl restart nginx
OR
sudo systemctl restart nginx

ด้วยวิธีนี้ คุณสามารถเปิดใช้งาน nginx เพื่อจัดการทั้งคำขอ HTTP และ HTTPS สำหรับบล็อกเซิร์ฟเวอร์หลายตัว

สุดท้ายนี้ ด้านล่างคือรายการบทความเกี่ยวกับการตั้งค่า SSL HTTPS บน Linux ทั่วไปและ FreeBSD

  1. การตั้งค่า HTTPS ด้วย Let's Encrypt SSL Certificate สำหรับ Nginx บน RHEL/CentOS
  2. รักษาความปลอดภัย Nginx ด้วย Let's Encrypt SSL Certificate ฟรีบน Ubuntu และ Debian
  3. วิธีรักษาความปลอดภัย Nginx ด้วย SSL และเข้ารหัสใน FreeBSD

นั่นคือทั้งหมดที่สำหรับตอนนี้. หากคุณทราบวิธีอื่นในการแก้ไขข้อผิดพลาดนี้ โปรดแจ้งให้เราทราบผ่านแบบฟอร์มคำติชมด้านล่าง