« Raspberry Pi でsuになれない話 | トップページ | Raspberry PiがWeb監視カメラに »

2020年11月 3日 (火)

Raspi httpsへの道

Rasberry PiをIoTデバイスにみたてて、Restletサーバーにhttpsで通信するよう構成してみた。

https通信は、クライアントからhttps通信リクエストがサーバーに届くと、サーバーは自分の証明書と公開鍵をクライアントに送り返す。クライアントはサーバーの証明書を確認してから、自分が作成した共通鍵をサーバーの公開鍵で暗号化してサーバーに送る。サーバーは暗号化された共通鍵を自分の秘密鍵で複合化する。この時点でクライアントとサーバーはともに同じ共通鍵を持つことができて、以後の通信はその共通鍵によって暗号化される。

まずはkeytoolを使って秘密鍵と公開鍵のキーペアを作成する。

[root@localhost work]# keytool -keystore restletkey.jks -alias restlet -genkey -keyalg RSA -keysize 2048 -sigalg "SHA1withRSA"
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: restlet.pathpilot.local
What is the name of your organizational unit?
[Unknown]: pathpilot
What is the name of your organization?
[Unknown]: restlet-server
What is the name of your City or Locality?
[Unknown]: Chuo-ku
What is the name of your State or Province?
[Unknown]: Tokyo
What is the two-letter country code for this unit?
[Unknown]: JP
Is CN=restlet.pathpilot.local, OU=pathpilot, O=restlet-server, L=Chuo-ku, ST=Tokyo, C=JP correct?
[no]: yes

Enter key password for <restlet>
(RETURN if same as keystore password):  <---パスワードはpasswordとした。
Re-enter new password:

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore restletkey.jks -destkeystore restletkey.jks -deststoretype pkcs12".
[root@localhost work]#

JKS keystoreをPKCS12にマイグレーションするようガイドが出たのでその通りに実行。
[root@localhost work]# keytool -importkeystore -srckeystore restletkey.jks -destkeystore restletkey.jks -deststoretype pkcs12
Enter source keystore password:
Entry for alias restlet successfully imported.
Import command completed: 1 entries successfully imported, 0 entries failed or cancelled

Warning:
Migrated "restletkey.jks" to Non JKS/JCEKS. The JKS keystore is backed up as "restletkey.jks.old".
[root@localhost work]#

 

サーバー側のコードはこんな感じ。

   Component restserver = new Component();

   // Add a new HTTP server listening on port 8010.
   Server server = restserver.getServers().add(Protocol.HTTPS, 8010);

   Series<Parameter> parameters = server.getContext().getParameters();
   parameters.add("sslContextFactory","org.restlet.engine.ssl.DefaultSslContextFactory");
   parameters.add("keystorePath","./restletkey.jks");    // restletkey.jksはjavaコードと同じディレクトリに置いた
   parameters.add("keystorePassword","password");
   parameters.add("keystoreType","JKS");
   parameters.add("keyPassword","password");

// Attach the sample application.
   restserver.getDefaultHost().attach("/command", new ServerDispatcher());

// Start the restserver.
   restserver.start();

 

このサーバーをChromeからアクセスしてみた。Chromeは”このサーバーは危ない”って言っている。

Chromewarning2

httpsでアクセスしているけれどもhttpsに取り消し線が付く。

Chromewarning5

その理由は証明書が信頼できるものではないから。自己証明書だから当然なんだけれど。。。。

Chromewarning3 Chromewarning4

FireFoxでもアクセスしてみた。同様に危ないって言っている。

Firefoxwarning1

詳細情報…をクリックして、”危険を承知で続行”をクリック。ちょっとビビる。

Firefoxwarning2

鍵に黄色!アイコンが付くけれども、Chromeよりは穏やかな表現。いずれにせよhttpsでアクセスできているようだ。

Firefoxwarning3

つまりBrowserは、サーバーが何者なのかちゃんと確認できなかったけれども、リクエストを発行したユーザーによってこのサーバーは信頼できるって言っている訳だから、とりあえずサーバーが送ってきた公開鍵を使って共通鍵を暗号化してサーバーに送り返し、https通信を始めたわけだ。

 

問題はRaspberry PiのPythonコード。例外を設定しないとhttpsで通信できない(してくれない)。常套手段はverify=Falseを設定することらしい。で、実行してみた。

response=requests.post("https://192.168.1.62:8010/next", auth=HTTPBasicAuth("user1","pass"), verify=False)

実行はできるけれども、Warningが出力された。

Warning (from warnings module):
File "/usr/lib/python3/dist-packages/urllib3/connectionpool.py", line 849
InsecureRequestWarning)
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
hello, my friend from Next <- サーバーが出力しているテキスト。とりあえずhttpsで受け取っている。 

ちゃんと金を払って認証局のお墨付きをもらわないといけないわけだ。まぁ、そうじゃなきゃ認証局の意味がないけれどね。

 

 

« Raspberry Pi でsuになれない話 | トップページ | Raspberry PiがWeb監視カメラに »

ラズパイ日記」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

« Raspberry Pi でsuになれない話 | トップページ | Raspberry PiがWeb監視カメラに »