CakePHP5入門【CakePHP5実用編⑧】WebSocketの暗号化

A子
開発環境のWebサーバが「SSL/TLS」に対応したのは良いんだけどさ
「http」ではうまく動いてたのに、「https」では(WebSocket関連が)動かなくなっちゃったよ
「http」ではうまく動いてたのに、「https」では(WebSocket関連が)動かなくなっちゃったよ

B美
実は「http」環境では「ws」、「https」環境では「wss」がWebSocketのプロトコルになるのよ
要するに、「https」環境下ではWebSocket側も暗号化通信に対応させなきゃダメ…ってこと
要するに、「https」環境下ではWebSocket側も暗号化通信に対応させなきゃダメ…ってこと

C菜
修正作業って、結構難しいでしょうか~?

B美
そうでもないわよ
だってWebSocketライブラリである「Ratchet」には、暗号化(wss)対応のクラスがきちんと用意されてるもの
だってWebSocketライブラリである「Ratchet」には、暗号化(wss)対応のクラスがきちんと用意されてるもの

A子
だったら安心だね
んじゃ、まずは「src/Command」の中にある「WebSocketServerCommand.php」の変更から?
んじゃ、まずは「src/Command」の中にある「WebSocketServerCommand.php」の変更から?

B美
そうね
まずは、先頭のuseするところなんだけど…
ここには、三行追加してね
(赤字が追加箇所)
次に「execute」メソッドだけど、$contextという連想配列を用意して、それを引数に「SecureServer」のオブジェクトを生成
あとは、それを「IoServer」の引数に渡すだけ…
(赤字が追加・変更箇所)
あ、「server.crt」や「server.key」のパスを間違えないように!
(WebサーバであるApache2が参照しているのは「/etc/apache/ssl/」ディレクトリだけど、一般ユーザ権限ではそのディレクトリにアクセスできないからね)
まずは、先頭のuseするところなんだけど…
ここには、三行追加してね
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface; use Ratchet\Http\HttpServer; use Ratchet\Server\IoServer; use Ratchet\WebSocket\WsServer; use React\EventLoop\Factory as LoopFactory; use React\Socket\Server as ReactServer; use Ratchet\Server\SecureServer; use React\Socket\SecureServer as ReactSecureServer; use React\Socket\SocketServer; |
次に「execute」メソッドだけど、$contextという連想配列を用意して、それを引数に「SecureServer」のオブジェクトを生成
あとは、それを「IoServer」の引数に渡すだけ…
public function execute(Arguments $args, ConsoleIo $io): void
{ $loop = LoopFactory::create(); $context = [ 'local_cert' => '/home/bimi/ssl/server.crt', //サーバ証明書 'local_pk' => '/home/bimi/ssl/server.key', //秘密鍵 'allow_self_signed' => true, 'verify_peer' => false ]; $socket = new SocketServer(WEBSOCKET_IP.':'.WEBSOCKET_PORT); $secureServer = new ReactSecureServer($socket, $loop, $context); $server = new IoServer(new HttpServer(new WsServer($this)), $secureServer, $loop); $io->out('WebSocketサーバを起動しました。'); $server->run(); } |
あ、「server.crt」や「server.key」のパスを間違えないように!
(WebサーバであるApache2が参照しているのは「/etc/apache/ssl/」ディレクトリだけど、一般ユーザ権限ではそのディレクトリにアクセスできないからね)



C菜
B美部長のユーザホームに「ssl」というディレクトリを作って、その中に「サーバ証明書(server.crt)」や「秘密鍵(server.key)」をコピーしたということでしょうか~?

B美
そういうこと

A子
ちょっと待って!
軽く流さずに、詳しい手順を教えてよ(苦笑)
軽く流さずに、詳しい手順を教えてよ(苦笑)

B美
仕方ないわねぇ
「MATE端末」を開いたら
…って感じかしら
(当然だけど「bimi:bimi」の箇所は適宜変更してね)
あ、コピーコマンド(cp)の末尾の「.」を忘れないように!
「MATE端末」を開いたら
mkdir ssl[Enter]
cd ssl[Enter] su[Enter] cp /etc/apache2/ssl/server.crt .[Enter] cp /etc/apache2/ssl/server.key .[Enter] chown bimi:bimi *[Enter] exit[Enter] |
…って感じかしら
(当然だけど「bimi:bimi」の箇所は適宜変更してね)
あ、コピーコマンド(cp)の末尾の「.」を忘れないように!


C菜
「chown」って、ファイルの所有者を変更するコマンドでしたよね~
あ、あとView側も修正が必要なんでしょうか~?
あ、あとView側も修正が必要なんでしょうか~?

B美
一ヶ所だけね
「templates/Chat」の中にある「index.php」のJavaScript部分なんだけど…
(赤字が変更箇所)
つまり、プロトコルである「ws」の箇所を「wss」に変えるだけでOKよ
「templates/Chat」の中にある「index.php」のJavaScript部分なんだけど…
const ws = new WebSocket("wss://<?= WEBSOCKET_IP ?>:<?= WEBSOCKET_PORT ?>"); |
つまり、プロトコルである「ws」の箇所を「wss」に変えるだけでOKよ


A子
ふむ
そこまで難しくはなかったね
そこまで難しくはなかったね

C菜
いえ、「サーバ証明書」や「秘密鍵」のパスとして、(間違って)「/etc/apache2/ssl」ディレクトリを指定しちゃいそうです~
その場合、絶対に動きませんよね~?
その場合、絶対に動きませんよね~?

B美
その通りよ
Linuxサーバにおいて、ファイルやディレクトリのパーミッション(の知識)がいかに重要か…ってことね
Linuxサーバにおいて、ファイルやディレクトリのパーミッション(の知識)がいかに重要か…ってことね

A子
な、なるほど
たしかに、気付けなかった場合、ドツボにハマるかもしれない…(苦笑)
あ、ちなみにそのパスを含んだファイル名の記述だけど、定数化しといたほうが良いと思うんだけど…
(本番環境への設置のためにも)
たしかに、気付けなかった場合、ドツボにハマるかもしれない…(苦笑)
あ、ちなみにそのパスを含んだファイル名の記述だけど、定数化しといたほうが良いと思うんだけど…
(本番環境への設置のためにも)

C菜
ですね~
「src/Command」の中にある「WebSocketServerCommand.php」、その「execute」メソッドを書き換えましょう~
(赤字が変更箇所)
もちろん、「config/const.php」のほうにも以下の二行を追加するです~
「src/Command」の中にある「WebSocketServerCommand.php」、その「execute」メソッドを書き換えましょう~
public function execute(Arguments $args, ConsoleIo $io): void
{ $loop = LoopFactory::create(); $context = [ 'local_cert' => CERT_FILE, 'local_pk' => PK_FILE, 'allow_self_signed' => true, 'verify_peer' => false ]; $socket = new SocketServer(WEBSOCKET_IP.':'.WEBSOCKET_PORT); $secureServer = new ReactSecureServer($socket, $loop, $context); $server = new IoServer(new HttpServer(new WsServer($this)), $secureServer, $loop); $io->out('WebSocketサーバを起動しました。'); $server->run(); } |
もちろん、「config/const.php」のほうにも以下の二行を追加するです~
define("CERT_FILE", "/home/bimi/ssl/server.crt"); //サーバ証明書
define("PK_FILE", "/home/bimi/ssl/server.key"); //秘密鍵 |




A子
うん
完璧じゃん
完璧じゃん