質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

1回答

1195閲覧

TLS対応にしているGo言語のサーバを、Dockerコンテナの中から使えるようにしたい

TomMurphy

総合スコア13

docker-compose

docker-composeとは、複数のコンテナで構成されるサービスを提供する手順を自動的し管理を簡単にするツール。composeファイルを使用しコマンド1回で設定した全サービスを作成・起動することが可能です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2023/05/07 04:32

実現したいこと

TLS対応にしているGo言語のサーバを、Dockerコンテナの中から使えるようにしたい

前提

GO言語を使ってサーバを作っています。これらのサーバをDockerコンテナに格納して、運用しやすくしたいと考えております。

発生している問題・エラーメッセージ

Dockerコンテナに格納すると、https(×http)通信が使えません。

cert.pem、key.pemを使わない場合、http://127.0.0.1:18888で、ブラウザに"hello"メッセージがされますが、cert.pem、key.pemを使ってhttps://127.0.0.1:18888とした場合、「このサイトにアクセスできません」と表示されます。

該当のソースコード

GO言語

1package main 2 3import ( 4 "flag" 5 "fmt" 6 "log" 7 "net/http" 8 "net/http/httputil" 9 "os" 10) 11 12var url_host string 13 14func handler(w http.ResponseWriter, r *http.Request) { 15 dump, err := httputil.DumpRequest(r, true) 16 if err != nil { 17 http.Error(w, fmt.Sprint(err), http.StatusInternalServerError) 18 return 19 } 20 fmt.Println(string(dump)) 21 fmt.Fprintf(w, "<html><body>hello</body></html>\n") 22} 23 24var addr = flag.String("addr", "127.0.0.1:18888", "http service address") // テスト 25 26func main() { 27 http.HandleFunc("/", handler) 28 fmt.Println("url_host:", url_host) 29 30 log.Println("start http listening :18888") 31 32 var httpErr error 33 if _, err := os.Stat("./cert.pem"); err == nil { 34 if httpErr = http.ListenAndServeTLS(*addr, "./cert.pem", "./key.pem", nil); httpErr != nil { 35 log.Fatal("No pem file with https error: ", httpErr.Error()) 36 } 37 } 38} 39

Dockerfile

1#FROM golang:apline 2FROM golang:1.16.3-alpine 3WORKDIR /go 4ADD . /go 5CMD ["go", "run", "main.go"]

docker

1version: '3' 2services: 3 app: 4 build: . 5 ports: 6 - "18888:18888" # "ホストのポート:コンテナのポート"

試したこと

上記のmain.go のfunc main()を以下のようにしている場合は,http(×https)で通信できます。

func main() { var httpServer http.Server http.HandleFunc("/", handler) log.Println("start http listening :18888") httpServer.Addr = ":18888" log.Println(httpServer.ListenAndServe()) }

補足情報(FW/ツールのバージョンなど)

■Windows10上のDocker for Windowsを使用しています。
■Dockerコンテナを使わないで、 windowsのコマンドプロンプトから起動する場合は、"https://127.0.0.1:18888"は問題なく起動します。

考察

考えてみれば、DockerコンテナへのアクセスにはTLSに関する情報が設定をしていないので、起動しないのは当然とも思えます。
そこで、

docker-compose start --tlscert="/go/cert.pem" --tlskey="/go/key.pem" (コンテナ内に置かれている場所)

やら、

docker-compose start --tlscert="c:\\user\\username\\go-docker\\cert.pem" --tlskey="c:\\user\\username\\go-docker\\cert.pem" (ローカルに置かれている場所)

なども試してみたのですが、上手く動かすことができませんでした。

ネットで色々探してみたのですが、これというものを見つけられておらず、頭を抱えています。
お助け頂けましたら、幸甚と存じます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2023/05/07 05:26

cert.pem、key.pemはどのようなコモンネームを持つ証明書なのでしょうか?
guest

回答1

0

ベストアンサー

Windowsのコマンドプロンプトから起動した場合にhttps通信できたとのことですが、コードから見るに出来る理由が見当たりません。
もしくは質問に情報が不足しているかもしれません。

Windowsのコマンドプロンプトから起動した場合に証明書をどの様に設定しましたか?

追記

TLSによるコードを確認してみました。

わかった問題点はDockerコンテナ内のリッスンポートが「127.0.0.1:18888」になっているのでDockerコンテナ外部からの接続に応答できないということです。
Dockerコンテナ内は別のネットワークに属しているので、ホストのブラウザとローカルアドレスで疎通できません。
Windows内で起動したプロセスはブラウザと同じネットワークホストにあるので「127.0.0.1」で接続可能です。

Goのコードの実行時に「-addr :18888」というオプションをつけて(Dockerfileを修正して)お試しください。
あと、/goはGOROOTなのでアプリコードを置くのは推奨されません。別の場所にアプリを置くとよいでしょう。

Dockerfile

1#FROM golang:apline 2FROM golang:1.16.3-alpine 3WORKDIR /app 4ADD . /app 5CMD ["go", "run", "main.go", "-addr", ":18888"]

おすすめの開発方法

オレオレ証明書の運用でブラウザテストする時、いくつか警告を黙らせる必要があったり、
簡易CAを起こしてルート証明書をスマホやPCにインストールという手法はマルウェアの手法に近いので
乱用するとご自身の環境の安全にも良くないです。
ブラウザが検証するサーバー証明書というのはしかるべきオーソリティに発行してもらったものを使うのが原則と考えましょう。
オレオレ証明書は独自の通信経路の安全確保などに使うくらいにとどめておくとよいでしょう。

オススメなのは外部の中継サービスであるngrokやcloudflared tunnelを利用する方法です。
外部のURLへのアクセスを手元のアドレスに中継してくれるという仕掛けです。

Goのサーバーはhttpで開発しておき、cloudflared というツールをインストール、

> cloudflared tunnel -url http://localhost:18888 2023-05-07T10:25:12Z INF +--------------------------------------------------------------------------------------------+ 2023-05-07T10:25:12Z INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): | 2023-05-07T10:25:12Z INF | https://xxxxxx-xxxx-xxx-xxxxxxxxxx.trycloudflare.com | 2023-05-07T10:25:12Z INF +--------------------------------------------------------------------------------------------+

という表示が出たら、表示にあるURLをブラウザで開きます。

この場合毎回URLが変化してしまうけれど、有効な証明書が生きている状態でテストできます。
Web技術の一部は有効な証明書がないと実行できないというものもありますので、この方法をよく使っています。
また、自分の管理下にあるドメインの場合はLet’sEncryptを使います。
もっとも楽なのはクラウドにデプロイしてクラウドの証明書発行サービスを利用することですね。

投稿2023/05/07 08:30

編集2023/05/08 23:28
nobonobo

総合スコア3367

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nobonobo

2023/05/07 09:35

その記事の通りにListenAndServeTLSを使ったコードを示してください。もちろんdockerでも同じです。
nobonobo

2023/05/07 09:37

あ、TLSを使ったコードに修正されましたね。またみてみてから追記します!
TomMurphy

2023/05/09 15:49

ご助言ありがとうございます。「オレオレ」につきましては、実験的ということでサーバに上げるときには、Let.s ..を使っています(Let.s...は、ベタベタのIPアドレスの指定ができないのでローカルでの試験では使い回しが悪いので)。現在、毎日すこしずつ時間を見つけて実験しておりますので、もうしばらくおまちいただけますようお願い致します。
TomMurphy

2023/05/10 14:39

散々、色々試したあげく、最初に頂いた、Dockerfileの内容に変更することで、無事問題を解決することができました。現在、Dockerの中で立ち上げたgoのサーバに対して、https://localhost:18888で表示されることを確認しました。 Dockerの中に潜ってしらべてみたところ、こんな感じになっていました。 ``` C:\Users\ebata\go-docker>docker-compose up -d WARNING: Compose V1 is no longer supported and will be removed from Docker Desktop in an upcoming release. See https://docs.docker.com/go/compose-v1-eol/ Creating network "go-docker_default" with the default driver Creating go-docker_app_1 ... done C:\Users\ebata\go-docker>docker container exec -it go-docker_app_1 sh /go # ps PID USER TIME COMMAND 1 root 0:00 go run main.go -addr :18888 108 root 0:00 /tmp/go-build1461432925/b001/exe/main -addr :18888 114 root 0:00 sh 120 root 0:00 ps ``` ただ、今なお、Dockerfile に追加した、CMD ["go", "run", "main.go","-addr",":18888"] の中の、"-addr:18888"の機能が分からずに"もんもん"としております( "docker" & "-addr"などで検索などしたのですが、上手くヒットしませんでした)。 ただ、cert.pem, key.pemを入れた状態でも、Dockerが使えることが分かったことは、今後のサーバ立ち上げに関して、かなり有益な知見となりました(実サーバ運用では、ご指摘の内容を反映してリスクを回避したいと思います)。 この度は、誠にありがとうございました。
nobonobo

2023/05/11 01:57

「-addr :18888」については質問者さんの挙げている「該当のソースコードのGo言語」の24行目にあるコマンドラインフラグの定義に対する指定です。
TomMurphy

2023/05/11 11:12

あ! そういうことですか。分かりました。ありがとうございます。とてもスッキリしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問