I'm having problems redirecting HTTP-traffic into HTTPS in my EC2 instance on a Golang-service. The connection works fine when going straight to https://sub.domain.com, but the redirect from HTTP doesn't seem to be working.
There is no load balancer and it's using only the net/http package as the web server.
I'm also using iptables that should be redirecting HTTP/HTTPS requests to ports 8080/8081 respectively.
Just to narrow down the possibilities, the security group applied to the instance has connections to ports 80 and 443 allowed from any IPv4 or IPv6 address.
Here is the server-code that serves HTTPS and is supposed to redirect HTTP requests;
// LetsEncrypt setup
certManager := autocert.Manager{
Prompt: autocert.AcceptTOS,
HostPolicy: autocert.HostWhitelist("sub.domain.com"), // your domain here
Cache: autocert.DirCache("certs"), // folder for storing certificates
}
server := &http.Server{
Addr: ":8081",
Handler: context.ClearHandler(http.DefaultServeMux),
TLSConfig: &tls.Config{GetCertificate: certManager.GetCertificate},
}
// open https server
err = server.ListenAndServeTLS("", "")
if err != nil {
fmt.Printf("ListenAndServe: %s
", err)
}
// redirect everything to https
go http.ListenAndServe(":8080", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
reqhost := strings.Split(r.Host, ":")[0]
http.Redirect(w, r, "https://" + reqhost + r.URL.Path, http.StatusMovedPermanently)
}))
Here are my PREROUTING rules from iptables, other chains are empty;
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
7 420 REDIRECT tcp -- eth0 any anywhere anywhere tcp dpt:https redir ports 8081
45 2508 REDIRECT tcp -- eth0 any anywhere anywhere tcp dpt:http redir ports 8080
Both redirects are getting packets on requests, but the 8080 just wont redirect the connection to the HTTPS side.
You are missing port
in the redirect
http.Redirect(w, r, "https://" + reqhost + r.URL.Path + ":" + port, http.StatusMovedPermanently)
You need to add port in there. Also you can use postman in the request to see what is the location URL that is sent.
Hope it helps.
I checked what was listening on my ports with
netstat -tulpn | grep LISTEN
..and there was apache listening on port 80. Either shutting it down or removing it works just fine.