Closed AlbinoGeek closed 4 years ago
I can't get this working whatsoever. I get the following error trying to access the server locally:
[HTTP Server] http: TLS handshake error from 127.0.0.1:54234: acme/autocert: missing server name
[HTTP Server] http: TLS handshake error from [::1]:54704: acme/autocert: server name component count invalid
And accessing the server remotely gives me Address Unreachable
v.s. using standard app.Listen
Hello @AlbinoGeek please check my reply on your previous issue as I am reading this new one
I think that it a log "issue", indeed the server is running on http:...:443 when accessing the https://...:80, the errors you got in your console maybe result of localhost testing instead of a domain or no? AutoTLS works on a linux (ubuntu) and windows systems here, can you give me more information please?
This may require #1577 to be solved first, as this is using AutoTLS
which I cannot get working in any configuration at the moment. I even tried (For the sake of this ticket) changing the NAT to allow 80->80
and 443->443
specifically, then running iris as root
:fearful:
As per more information:
$ uname -a
Linux doom.broughton.lan 5.7.11-200.fc32.x86_64 #1 SMP Wed Jul 29 17:15:52 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ go version
go version go1.14.6 linux/amd64
$ cat go.sum | grep iris | cut -d' ' -f1,2
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod
github.com/iris-contrib/httpexpect/v2 v2.0.5
github.com/iris-contrib/httpexpect/v2 v2.0.5/go.mod
github.com/iris-contrib/jade v1.1.4
github.com/iris-contrib/jade v1.1.4/go.mod
github.com/iris-contrib/pongo2 v0.0.1
github.com/iris-contrib/pongo2 v0.0.1/go.mod
github.com/iris-contrib/schema v0.0.2
github.com/iris-contrib/schema v0.0.2/go.mod
github.com/kataras/iris/v12 v12.1.9-0.20200809192844-da029d6f3722
github.com/kataras/iris/v12 v12.1.9-0.20200809192844-da029d6f3722/go.mod
It is fairly common in my experience for an HTTP server behind this sort of proxy/NAT to still function (just without the SSL portion) on testing domains such as localhost
. It is worth noting that I have put real domains in the AutoTLS code as follows (redacted however):
app.Run(iris.AutoTLS(":443", "my.domain", "me@my.domain"))
This binds to :80 because of the automatic HTTP -> HTTPS server, the iris.TLSNoRedirect
is missing from the iris.AutoTLS
function. For users reading this issue, please follow this.
@AlbinoGeek I think you can close this issue now?
I can close #1577 , but not this issue. This issue remains as a bug in the logging that shows http://localhost:443
even when its actually listening on 0.0.0.0:443
.
Alright, after speaking with @kataras a bit, here's what we've come to:
For case 1) The server is correctly listening on 0.0.0.0:443
even though it displays localhost:443
in the text, this is to give the user a click-able link in their console, as opposed to the former which is not a real IP address. Totally understandable.
For case 2) The same logic as case 1 should apply, but is not currently.
In regards to no viable challenge type found
found in #1577 , this is being fixed now.
Now when using AutoTLS
with known domain, something like Now listening on: https://example.com
will be displayed instead:
Thanks @AlbinoGeek, your issue and contribution was one of the best we've ever had!
This aaaaaaaaaaalmost works, just one more change (messaged you on git)
This is the only remaining blocker on my NAT situation.
@AlbinoGeek These lines are commented out (and the host:port part fixed), give it a shot
Commits up to and including ff5e43f have fixed this!
However, due to the way golang/crypto works, external port 80 cannot be changed, this is not iris fault. Every other port can be changed successfully now, to work behind a NAT or proxy for example.
For anyone who finds this in the future (I'm going to PR an example), the following code works:
This allows a system where NAT or Port Forwarding creates the following rules to host iris.
As a very positive side-effect, AutoTLS effectively doesn't require root
when running as configured:
Debian 9 or older, Fedora 30 or older, RedHat/CentOS 7 or older, Ubuntu 16 or older,
# Forward internal 8443 to external 443
sudo iptables -t nat -A PREROUTING -p tcp --dport 8443 -j REDIRECT --to-ports 443
sudo iptables -t nat -A OUTPUT -p tcp --dport 8443 -j REDIRECT --to-ports 443
# Forward internal 8080 to external 80
sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-ports 80
sudo iptables -t nat -A OUTPUT -p tcp --dport 8080 -j REDIRECT --to-ports 80
## You may also need to run this, if it's not working:
## echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
## and once it's all working, you need to save the firewall rules, or it's lost on reboot:
## iptables-save
Debian 10 or newer, Fedora 32 or newer, RedHat/CentOS 8 or newer, Ubuntu 18 or newer
# Enable Port Forwarding
sudo firewall-cmd --zone=external --add-masquerade
# Forward internal 8443 to external 443
sudo firewall-cmd --zone=external --add-forward-port=port=443:proto=tcp:toport=8443
# Forward internal 8080 to external 80
sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080
## For added security, add ":toaddr=127.0.0.1" to the end of each of the above lines:
## sudo firewall-cmd --zone=external --add-forward-port=port=443:proto=tcp:toport=8443:toaddr=127.0.0.1
## sudo firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=127.0.0.1
## Then, change `internalHost` to "127.0.0.1" below
## And again, once it's working, save the rules so they're not lost on reboot:
## sudo firewall-cmd --runtime-to-permanent
package main
import (
"fmt"
"net/http"
"time"
"github.com/kataras/iris/v12"
"github.com/spf13/pflag"
)
var (
adminEmail = pflag.String("admin-email", "you@example.com", "Administrator email sent to LetsEncrypt")
domain = pflag.String("domain", "example.com", "Canonical domain for URL generation")
externalHost = pflag.String("external-host", "0.0.0.0", "HTTP(S) Hostname used externally")
internalHost = pflag.String("internal-host", "0.0.0.0", "HTTP Hostname used internally")
internalPortPlain = pflag.Int("internal-port", 8080, "HTTP Port used internally")
internalPortSecure = pflag.Int("internal-port-secure", 8443, "HTTPS Port used internally")
)
func main() {
pflag.Parse()
app = iris.New()
app.Get("/", func(ctx iris.Context) {
ctx.JSON(map[string]interface{}{
"time": time.Now().Unix(),
})
})
tlsAddr := fmt.Sprintf("%s:%d", *internalHost, *internalPortSecure)
domains := fmt.Sprintf("%s www.%s your.%s", *domain, *domain, *domain)
app.Run(iris.AutoTLS(tlsAddr, domains, *adminEmail, iris.AutoTLSNoRedirect(fallbackServer)))
}
// Without this, the ACME HTTP-01 challenge would fail
func fallbackServer(acme func(http.Handler) http.Handler) *http.Server {
srv := &http.Server{
Addr: fmt.Sprintf("%s:%d", *externalHost, *internalPortPlain),
Handler: acme(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, fmt.Sprintf("https://%s/", *domain), iris.StatusTemporaryRedirect)
})),
}
go srv.ListenAndServe()
return srv
}
# Test Internal plaintext ip/port
$ curl http://localhost:8080
<a href="https://example.com/">Temporary Redirect</a>.
# Test external plaintext ip/port
$ curl http://example.com
<a href="https://example.com/">Temporary Redirect</a>.
# Test external secure ip/port
$ curl https://example.com
{
"time": 1597304304
}
Good job @AlbinoGeek! If we can dockerize this example and put it on https://github.com/kataras/iris/tree/master/_examples/http-server as nat-letsencrypt
will be great, waiting for your PR!
Describe the bug Using the example AutoTLS code results in
http://localhost:443
output Using AutoTLS code for0.0.0.0:443
results inhttp://0.0.0.0
outputTo Reproduce Steps to reproduce the behavior:
0.0.0.0:443
Expected behavior AutoTLS hosting on
https://0.0.0.0
in both casesScreenshots
Desktop (please complete the following information):
iris.Version