Closed dragonpaw closed 4 years ago
To clarify: Debug mode doesn't disable auto HTTPS redirects -- it has nothing to do with them -- it just enables DEBUG level logging (which there isn't too much of at this point, but I'm sure more will be added with time).
What exactly are you trying to test? What's the problem here, exactly? Your config is served over HTTPS, but redirects to HTTP, I assume for a host that is served by the same config, hence the loop.
I'll need more info in order to be helpful, since just saying "some error" and using clipped or redacted configs isn't going to get us anywhere. :)
Ideally, we need to be able to reproduce the bug in the most minimal way possible. This allows us to write regression tests to verify the fix is working. If we can't reproduce it, then you'll have to test our changes for us until it's fixed -- and then we can't add test cases, either.
I've attached a template below that will help make this easier and faster! It will ask for some information you've already provided; that's OK, just fill it out the best you can. :+1:
I've also included some helpful tips below the template. Feel free to let me know if you have any questions!
Thank you again for your report, we look forward to resolving it!
## 1. Environment
### 1a. Operating system and version
```
paste here
```
### 1b. Caddy version (run `caddy version` or paste commit SHA)
```
paste here
```
### 1c. Go version (if building Caddy from source; run `go version`)
```
paste here
```
## 2. Description
### 2a. What happens (briefly explain what is wrong)
### 2b. Why it's a bug (if it's not obvious)
### 2c. Log output
```
paste terminal output or logs here
```
### 2d. Workaround(s)
### 2e. Relevant links
## 3. Tutorial (minimal steps to reproduce the bug)
Environment: Please fill out your OS and Caddy versions, even if you don't think they are relevant. (They are always relevant.) If you built Caddy from source, provide the commit SHA and specify your exact Go version.
Description: Describe at a high level what the bug is. What happens? Why is it a bug? Not all bugs are obvious, so convince readers that it's actually a bug.
Tutorial: What are the minimum required specific steps someone needs to take in order to experience the same bug? Your goal here is to make sure that anyone else can have the same experience with the bug as you do. You are writing a tutorial, so make sure to carry it out yourself before posting it. Please:
curl
.Example of a tutorial:
Create a config file: ``` { ... } ``` Open terminal and run Caddy: ``` $ caddy ... ``` Make an HTTP request: ``` $ curl ... ``` Notice that the result is ___ but it should be ___.
@dragonpaw something that has been added recently is the ability to do some internal integration testing.
This will work with public hostnames, internally it will dial localhost instead of the public dns ip address. https://github.com/caddyserver/caddy/blob/178ba024fea4db2b91fd159da629f0a8588f119a/caddytest/caddytest.go#L222-L226
This will not however work with ACME servers but with a small modification to your Caddyfile you could use caddy's new internal CA (smallstep) to issue certificates for you or you can use locally made self signed certs (the caddytest.Assert...
methods ignore certificate verification).
If you are comfortable running some go code.
func TestRespondHttps(t *testing.T) {
// arrange
caddytest.InitServer(t, `
{
http_port 9080
https_port 9443
}
www.cnn.com:9443 {
# choose your cert management options (tls internal is very cool)
# tls internal - load via the internal cert manager
# tls /a.caddy.localhost.crt /a.caddy.localhost.key - load using the static certs shipped with the caddytests
respond /version 200 {
body "hello from www.cnn.com"
}
}
`, "caddyfile")
// act and assert
caddytest.AssertGetResponse(t, "https://www.cnn.com:9443/version", 200, "hello from www.cnn.com")
}
Finally this is a new testing approach which has few bugs on Windows, if you are a windows user your experiences could help with #3191
Let me know if this is useful.
To clarify: Debug mode doesn't disable auto HTTPS redirects -- it has nothing to do with them -- it just enables DEBUG level logging (which there isn't too much of at this point, but I'm sure more will be added with time).
I didn't expect it to. I was hoping it might add interesting info to the logs. It didn't, but that's a different issue.
What exactly are you trying to test? What's the problem here, exactly? Your config is served over HTTPS, but redirects to HTTP, I assume for a host that is served by the same config, hence the loop.
I am expecting to be able to 100% verify that a configuration under test behaves properly before I let it within 10 miles of production. There's absolutely zero chance that I will deploy an http config, that I haven't tested. Running an httpd within a container and sending it http requests with appropriate Host headers is a pretty good way to be sure that it will behave as desired once it's in use. To that end, I should be able to configure it for, as in this example, to redirect 'example.com/~ash/foo' to 'ash.example.com/foo`. I wish to be able to verify that the config I has will reliably do that, long, long before it's anywhere near production hosts. If I cannot confirm that, I will consider the service unsuitable for production use, and never use it. I'm not about to try to debug httpd configs in production when I can do so before then.
Perhaps this is a philosophical thing. But for me, as a long-time devops engineer, software needs to be able to be tested before it reaches production. So I'm looking for help in finding out if caddy is appropriate for me in this way.
I'll need more info in order to be helpful, since just saying "some error" and using clipped or redacted configs isn't going to get us anywhere. :)
That's cool, but neither of those are true. The config wasn't redacted, and the error message was exactly pasted. (As seen in the last line of the 3rd code block: http: error: SSLError: HTTPSConnectionPool(host='localhost', port=443): Max retries exceeded with url: /~ash/foo (Caused by SSLError(SSLError(1, '[SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1076)'))) while doing GET request to URL: https://localhost/~ash/foo
)
I referred to the error as "some error" on the text directly below the error.
Ideally, we need to be able to reproduce the bug in the most minimal way possible. This allows us to write regression tests to verify the fix is working. If we can't reproduce it, then you'll have to test our changes for us until it's fixed -- and then we can't add test cases, either.
Cool, so the config I provided will do exactly that. It's 100% reproducible with the information I've provided. I can even upload the resulting docker container someplace if you like. I shortened the config enough to prove it was reproducible, which is I think maybe what you incorrectly labeled as 'redacting'.
I've attached a template below that will help make this easier and faster! It will ask for some information you've already provided; that's OK, just fill it out the best you can. 👍
The only thing I didn't give before is the version of docker I was using for the build. But sure...
Thank you again for your report, we look forward to resolving it!
Template
## 1. Environment ### 1a. Operating system and version
Docker 2.2.0.4 under Windows 10-64,
1b. Caddy version (run
caddy version
or paste commit SHA)hub.docker.com: 2.0.0-beta.19-alpine caddy version: v2.0.0-beta.19 h1:6kbQ5jf/lWjD+o3uuq7rnfrvw+x5UU3tuwGpZsLKr7M=
1c. Go version (if building Caddy from source; run
go version
)Not built from source.
2. Description
2a. What happens (briefly explain what is wrong)
2b. Why it's a bug (if it's not obvious)
Because opinionated old SREs won't put services in production if they can't be put under test. So if I can't bounce a http request off of it with appropriate Host headers, and see the redirects and content I expect to, there's no way I'll ever let it be used by real clients.
2c. Log output
$ http http://localhost:80/~ash/foo Host:example.com--verbose
GET /~ash/foo HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: example.com
User-Agent: HTTPie/0.9.8
HTTP/1.1 308 Permanent Redirect
Connection: close
Content-Length: 0
Date: Sun, 29 Mar 2020 00:25:52 GMT
Location: https://example.com/~ash/foo
Server: Caddy
$ http https://localhost/~ash/foo Host:example.com --verbose
http: error: SSLError: HTTPSConnectionPool(host='localhost', port=443): Max retries exceeded with url: /~ash/foo (Caused by SSLError(SSLError(1, '[SSL: TLSV1_ALERT_INTERNAL_ERROR] tlsv1 alert internal error (_ssl.c:1076)'))) while doing GET request to URL: https://localhost/~ash/foo
2d. Workaround(s)
Can't find any.
2e. Relevant links
@dragonpaw I believe you have stumbled on this bug in httpie from 2015 https://github.com/jakubroztocil/httpie/issues/414
As per their issue the recommendation is to edit your /etc/hosts
file
http --verify=no https://example.com/~ash/foo --verbose
GET /~ash/foo HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: example.com
User-Agent: HTTPie/0.9.4
HTTP/1.1 301 Moved Permanently
Content-Length: 0
Date: Sun, 29 Mar 2020 06:26:26 GMT
Location: http://ash.example.com/foo
Server: Caddy
## also with curl
curl -i https://example.com/~ash/foo -k
HTTP/2 301
location: http://ash.example.com/foo
server: Caddy
content-length: 0
date: Sun, 29 Mar 2020 06:16:54 GMT
Btw here is an integration test for you (no hosts name changes needed)
func TestRespondHttps(t *testing.T) {
// arrange
caddytest.InitServer(t, `
{
acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
email ash@example.com
admin off
local_certs
debug
http_port 9080
https_port 9443
}
example.com {
@foo {
path_regexp a ^/~ash(.*)
}
redir @foo http://ash.example.com{http.regexp.a.1} permanent
root * /sites/example.com
file_server
}
`, "caddyfile")
// act and assert
caddytest.AssertRedirect(t, "https://example.com:9443/~ash/foo", "http://ash.example.com/foo", 301)
}
Good find on the httpie bug! Thank you.
Given that, I think what would have helped in this case would be two things:
You can force http by
http://example.com {
...
The error message you were getting was
http: TLS handshake error from [::1]:56538: no certificate available for 'localhost'
But unless you understand how TLS and SNI work that might not mean much. The TLS / SNI processes are quite separate from the hostname matching.
Sure docs on the use of curl would handy for anyone in a SRE role.
Not sure where you saw the 'no certificate ... for localhost' message, as I never got that one.
I do think some documentation and logging improvements would help in these kinds of situations, but as I have enough to continue now, feel free to close the issue if you'd like.
Thank you for your help.
I've got a moderately complex setup that I'm trying to migrate from nginx to Caddy2, with redirects and regex and fun stuff like that. So of course I want to run this thing locally and double check the config before putting it in place in production. Unfortunately, this kinda seems impossible with the https features as it is today.
Given this Dockerfile:
And a Caddyfile that looks a little like:
I'd want to be able to do a lot of testing on the redirects and such before, but, using httpie for local test:
So I can't do the tests over http, since it always redirects to https, even in debug mode, and this doesn't seem able to be disabled. And trying using https gives some error that doesn't seem to have anything to do with local certificates. And I can't use this in production where the hostnames actually route to the host, because I can't test it.
I'm really not sure how to make progress at this point.