การเข้ารหัสการส่งข้อมูล-ssl/tls

คำถาม:

จะทำอย่างไรให้การสื่อสารระหว่าง Workerman มีความปลอดภัย?

คำตอบ:

วิธีที่สะดวกคือการเพิ่มชั้นการเข้ารหัส SSL ขึ้นอยู่กับโปรโตคอลการสื่อสาร เช่น wss, https โปรโตคอลทั้งสองนี้ใช้การส่งข้อมูลที่เข้ารหัสผ่าน SSL มีความปลอดภัยสูง Workerman มีการสนับสนุน SSL (ต้องใช้ Workerman>=3.3.7) เพียงแค่ตั้งค่าคุณสมบัติบางประการก็สามารถเปิดใช้งาน SSL ได้

แน่นอนว่านักพัฒนาสามารถสร้างกลไกการเข้ารหัสและถอดรหัสของตนเองได้โดยอิงจากอัลกอริธึมการเข้ารหัสบางประเภท

วิธีเปิดใช้งาน ssl ใน Workerman มีดังนี้:

การเตรียมการ:

  1. Workerman รุ่นต้องไม่ต่ำกว่า 3.3.7

  2. PHP ต้องติดตั้งส่วนขยาย openssl

  3. ได้ขอใบรับรอง (ไฟล์ pem/crt และไฟล์ key) ที่เก็บไว้ใน /etc/nginx/conf.d/ssl

โค้ด:

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// ใบรับรองควรเป็นใบรับรองที่ขอมา
$context = array(
    'ssl' => array(
        'local_cert'        => '/etc/nginx/conf.d/ssl/server.pem', // สามารถใช้ไฟล์ crt ได้
        'local_pk'          => '/etc/nginx/conf.d/ssl/server.key',
        'verify_peer'       => false,
        'allow_self_signed' => true, // หากเป็นใบรับรองที่เซ็นเอง จำเป็นต้องเปิดใช้งานตัวเลือกนี้
    )
);
// ที่นี่ตั้งค่าเป็นโปรโตคอล websocket ก็สามารถใช้โปรโตคอล http หรือโปรโตคอลอื่นได้
$worker = new Worker('websocket://0.0.0.0:443', $context);
// ตั้งค่า transport เพื่อเปิดใช้งาน ssl
$worker->transport = 'ssl';
$worker->onMessage = function(TcpConnection $con, $msg) {
    $con->send('ok');
};

Worker::runAll();

เปิดใช้งาน SNI (Server Name Indication) ใน Workerman SNI(Server Name Indication)

เพื่อให้สามารถผูกใบรับรองหลายใบในที่อยู่ IP และพอร์ตเดียวกันได้

การรวมไฟล์ใบรับรอง .pem และ .key:

รวมเนื้อหาของไฟล์ .pem และไฟล์ .key ของแต่ละใบรับรองเข้าด้วยกัน โดยใส่เนื้อหาของไฟล์ .key ที่ส่วนท้ายของไฟล์ .pem (ถ้าไฟล์ .pem มี private key อยู่แล้วสามารถข้ามได้)

โปรดทราบว่าเป็นใบรับรองเดียว ไม่ต้องรวมใบรับรองทั้งหมดไว้ในไฟล์เดียว

ตัวอย่างเนื้อหาในไฟล์ pem ที่รวมแล้วของ host1.com.pem อาจมีลักษณะดังนี้:

-----BEGIN CERTIFICATE-----
MIIGXTCBA...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFBzCCA...
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAA....
-----END RSA PRIVATE KEY-----

โค้ด:

<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$context = array(
    'ssl' => array(
        'SNI_enabled' => true, // เปิดใช้งาน SNI
        'SNI_server_certs' => [ // ตั้งค่าใบรับรองหลายใบ
            'host1.com' => '/path/host1.com.pem', // ใบรับรอง 1
            'host2.com' => '/path/host2.com.pem', // ใบรับรอง 2
        ],
        'local_cert' => '/path/default.com.pem', // ใบรับรองเริ่มต้น
        'local_pk'   => '/path/default.com.key',
    )
);
$worker = new Worker('websocket://0.0.0.0:443', $context);
$worker->transport = 'ssl';
$worker->onMessage = function(TcpConnection $con, $msg) {
    $con->send('ok');
};

Worker::runAll();