보안 전송 - SSL/TLS
질문:
Workerman과의 통신을 어떻게 보안할 수 있습니까?
답변:
가장 편리한 방법은 통신 프로토콜 상위에 SSL 암호화 계층을 추가하는 것입니다. 예를 들어 wss, https 프로토콜은 모두 SSL 암호화 전송을 기반으로 하므로 매우 안전합니다. Workerman은 본인이 SSL을 지원합니다(Workerman>=3.3.7
버전 이상 필요), 속성을 설정하여 SSL을 쉽게 활성화할 수 있습니다.
물론, 개발자는 어떤 암호화/복호화 알고리즘을 기반으로 자체 암호화/복호화 메커니즘을 구현할 수도 있습니다.
Workerman에서 SSL 활성화 방법은 다음과 같습니다:
준비 작업:
- Workerman 버전은 3.3.7 이상이어야 합니다.
- PHP에 openssl 확장이 설치되어 있어야 합니다.
- 인증서(pem/crt 파일 및 키 파일)가 /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, // 자체 서명된 인증서인 경우 이 옵션을 활성화해야 합니다
)
);
// 여기서는 웹소켓 프로토콜을 설정했지만, 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();
Workerman에서 서버 이름 지시 SNI (Server Name Indication) 활성화
동일한 IP와 포트에서 여러 인증서를 바인딩할 수 있도록 합니다.
.pem 및 .key 파일 병합:
각 인증서의 .pem 및 해당 .key 파일의 내용을 병합하고, .key 파일의 내용을 .pem 파일 끝에 추가합니다.(.pem 파일 내에서 이미 개인 키가 포함되어 있는 경우 무시할 수 있습니다.)
개별 인증서를 한 파일에 모두 복사하지 말아야 함을 주의하세요.
예를 들어 host1.com.pem을 병합한 후의 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();