英文:
Golang ListenAndServeTLS returns data when not using https in the browser
问题
以下是我的tls后端代码:
package main
import (
"fmt"
"net/http"
)
const (
PORT = ":8443"
PRIV_KEY = "./private_key"
PUBLIC_KEY = "./public_key"
)
func rootHander(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Nobody should read this.")
}
func main() {
http.HandleFunc("/", rootHander)
err := http.ListenAndServeTLS(PORT, PUBLIC_KEY, PRIV_KEY, nil)
if err != nil {
fmt.Printf("main(): %s\n", err)
}
}
这些密钥是使用以下两行生成的:
openssl genrsa -out private_key 2048
openssl req -new -x509 -key private_key -out public_key -days 365
当我启动tls服务器,并使用浏览器访问网站(https://example.com:8443),我得到了预期的结果,在忽略浏览器警告之后:
Nobody should read this.
到目前为止一切都很好。
现在,当我将浏览器指向http://example.com:8443(注意使用的是http,而不是https),我在Firfox中得到了以下结果(Chrome也是一样的,但是会下载网站):
问题:为什么会有一个问号?
英文:
The following is my tls backend:
package main
import (
"fmt"
"net/http"
)
const (
PORT = ":8443"
PRIV_KEY = "./private_key"
PUBLIC_KEY = "./public_key"
)
func rootHander(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Nobody should read this.")
}
func main() {
http.HandleFunc("/", rootHander)
err := http.ListenAndServeTLS(PORT, PUBLIC_KEY, PRIV_KEY, nil)
if err != nil {
fmt.Printf("main(): %s\n", err)
}
}
The keys are generated using these two lines:
openssl genrsa -out private_key 2048
openssl req -new -x509 -key private_key -out public_key -days 365
When I start the tls server, and visit the site with a browser (https://example.com:8443) I get the expected result, after ignoring the browser warning:
Nobody should read this.
So far everything is cool.
Now, when I point my browser to http://example.com:8443 (notice that http is used, not https) I get the following result for Firfox (Chrome does the same, but downloading the site):
Question: Why is there a question mark?
答案1
得分: 8
如果将输出导入到od中,curl -k -3 http://localhost:8443 | od -A n -t x1
,你会得到以下字节序列 15 03 01 00 02 02 0a
,这是由浏览器渲染/处理的。
根据https://code.google.com/p/go/issues/detail?id=2253,这代表了TLS的意思是“我不明白你说的话”。
英文:
If you pipe the output into od, curl -k -3 http://localhost:8443 | od -A n -t x1
, you get the following sequence of bytes 15 03 01 00 02 02 0a
which is rendered/handled by the browser.
Which, according to https://code.google.com/p/go/issues/detail?id=2253, is TLS for "I didn't understand what you said."
答案2
得分: 4
如果仍然相关的话:
http.ListenAndServeTLS(...)
接受证书和私钥,而不是公钥和私钥。
英文:
If at all still relevent:
http.ListenAndServeTLS(...)
takes certificate and private key not public & private key.
答案3
得分: 2
以下是将请求从端口80重定向到443并使用类似于lets encrypt的CA提供TLS证书的一些代码。我知道使用lets encrypt时,您需要引用生成的fullchain.pem文件和privkey.pem文件。
自签名的最大问题是在生产环境中不太可行。在使用golang时,我们需要非常具体地配置我们的应用程序,因此在准备启动时,正确附加TLS证书这样的简单事项是一个重要的主题。
以下是我实际用于启动静态网站的一些简单代码:
package main
import (
"net/http"
"log"
)
func redirect(w http.ResponseWriter, req *http.Request) {
// 从req.Host中删除/添加非默认端口
target := "https://" + req.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
log.Printf("redirect to: %s", target)
http.Redirect(w, req, target, http.StatusTemporaryRedirect)
}
func main() {
// 定义一个变量,用于指定FileServer目录,这里是./static/
var fs = http.FileServer(http.Dir("static"))
// 表达处理函数
http.Handle("/", fs)
// 我们应该重定向端口80上的请求
go http.ListenAndServe(":80", http.HandlerFunc(redirect))
// 最后,我们监听请求并在特定端口上提供服务
http.ListenAndServeTLS(":443", "fullchain.pem", "privkey.pem", nil)
}
<details>
<summary>英文:</summary>
Here is some code to redirect requests on port 80 to 443 and to serve up tls certificates using a CA like lets encrypt. I know that with lets encrypt ([letsencrypt.org][1]) you want to reference the resulting fullchain.pem file as well as the privkey.pem.
The biggest problem with self signing is that it wont be very viable in production. With golang we really configure our applications quite specifically so something simple like attaching tls certs properly is an important topic when we are ready to launch.
here some simple code I have actually used to launch a static site:
package main
import (
"net/http"
"log"
)
func redirect(w http.ResponseWriter, req *http.Request) {
// remove/add not default ports from req.Host
target := "https://" + req.Host + req.URL.Path
if len(req.URL.RawQuery) > 0 {
target += "?" + req.URL.RawQuery
}
log.Printf("redirect to: %s", target)
http.Redirect(w, req, target,
http.StatusTemporaryRedirect)
}
func main() {
//define a variable for the FileServer directory in this case ./static/
var fs = http.FileServer(http.Dir("static"))
//express the handler function
http.Handle("/", fs)
//We should redirect requests on port 80
go http.ListenAndServe(":80", http.HandlerFunc(redirect))
//finally we Listen for requests and serve them up on a specific port
http.ListenAndServeTLS(":443", "fullchain.pem", "privkey.pem", nil)
}
[1]: http://letsencrypt.org
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论