Edited at

net/httpでポート443のHTTPSサーバーを立ち上げるまで

More than 3 years have passed since last update.

動的言語しかやったこと無い私ですが、ひょんなことからGoにふれてみることにしました。

まだ、チュートリアルを読んだり、Effective Goを読んでみたりのレベルですが・・・


環境


  • CentOS6.7


    • Go 1.5.2




参考にしたサイト


まずはオレオレ証明書を作ってみる

証明書無いと動かないのでオレオレ証明書をopensslで作る(詳細版)を参考に証明書を作成

$ openssl genrsa 2048 > myself.key

$ openssl req -new -key myself.key > myself.csr
$ openssl x509 -days 3650 -req -signkey myself.key < myself.csr > myself.crt
$ mkdir -p ssl/development/
$ mv myself.crt ssl/development
$ mv myself.key ssl/development


Goでhttpsサーバーを書く

mainの一行(http.ListenAndServeTLS(":50124", "ssl/development/myself.crt", "ssl/development/myself.key", nil) )で作成したオレオレ証明書を食わせてます。今回はログインを想定した内容でフォームの値を確認するところまで記載しています。GoのHTTPSサーバー自体のポートは50124で起動するようにしています


server.go

package main

import (
"fmt"
"html/template"
"log"
"net/http"
"strings"
)

func login(w http.ResponseWriter, r *http.Request) {
fmt.Println("method:", r.Method) //リクエストを取得するメソッド
if r.Method == "GET" {
t, _ := template.ParseFiles("login.gtpl")
t.Execute(w, nil)
} else {
r.ParseForm()
//ログインデータがリクエストされ、ログインのロジック判断が実行されます。
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
}
}

func main() {
http.HandleFunc("/login", login) //アクセスのルーティングを設定します

err := http.ListenAndServeTLS(":50124", "ssl/development/myself.crt", "ssl/development/myself.key", nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}


以下ログインフォームのテンプレート


login.gtpl

<html>

<head>
<title></title>
</head>
<body>
<form action="/login" method="post">
ユーザ名:<input type="text" name="username">
パスワード:<input type="password" name="password">
<input type="submit" value="ログイン">
</form>
</body>
</html>


SSLってポート443じゃ???

今回はrootではないユーザーでgoのHTTPSサーバーを起動させることを想定していますので、root以外のユーザーだとポート1024以上ではないとポートをlistenできないので、GoのHTTPサーバーを80番や443番ポートでListenする方法を調べたを参考にiptablesでポートフォワーディングして50124につなぎます。

ポート周りの設定はiptablesに寄せる方針です。

# Firewall configuration written by system-config-firewall

# Manual customization of this file is not recommended.
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# HTTP
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 50123
# HTTPS
-A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 50124
COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 443 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 50123 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 50124 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT


  • *filterに443と50124ポートのポート開放の設定を

  • *natに443ポートをlistenした場合は50124にポートフォワーディングをする設定を

書きます。

(上記内容は80番ポートの設定も一緒に記載しています)


Goのサーバーを起動してみる

root以外のユーザーで起動してみます

go run server.go

ブラウザで https://localhost/login vagrantとかなら https://{IPアドレス}/login にアクセスしてみください。


最後に

HTTPSとHTTPをserver.goで同時に動かしたいんだけども方法がわからない・・・・・