Resource icon

Reverse Proxy using Caddy (with optional automatic TLS)

KevDog

Patron
Joined
Nov 26, 2016
Messages
462
Ok - thanks for clarification. The caddy website is frustrating. I'm looking for some specific documentation and examples (like the one's you provided). How do you set TLS version parameters, ciphers etc? How do you re-encrypt to a TLS enabled backend server? I know its possible with caddy but the website isn't help me out a lot, either that or I don't know where to look. I'm coming from the nginx side of the equation.
 
Joined
Jan 27, 2020
Messages
577
@KevDog You may want to look into nginx as a reverse proxy setup. It's got a steeper learning curve compared to caddy but there is a bigger community to learn from and ask.
 

KevDog

Patron
Joined
Nov 26, 2016
Messages
462
@mistermanko Maybe I'll just stick with nginx. There are definitely some nice features with caddy, however the community definitely seems smaller. I'm pretty familiar with nginx but was just interested in maybe a different way to look at things.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
How do you set TLS version parameters, ciphers etc?
I'm not aware that you're able to do this, and certainly it isn't intended that you'd do it in normal usage--Caddy implements a modern, sane TLS configuration on its own.
 

KevDog

Patron
Joined
Nov 26, 2016
Messages
462
@danb35 -- I'd agree with you to some extent however it would be nice if caddy actually published what it used as its "modern, sane TLS configuration".
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
it would be nice if caddy actually published what it used as its "modern, sane TLS configuration".
I guess, though much of that can be determined experimentally:
Code:
[root@neth-test testssl.sh]# ./testssl.sh https://heimdall.familybrown.org

###########################################################
    testssl.sh       3.1dev from https://testssl.sh/dev/
    (e0d7945 2020-04-15 17:16:06 -- )

      This program is free software. Distribution and
             modification under GPLv2 permitted.
      USAGE w/o ANY WARRANTY. USE IT AT YOUR OWN RISK!

       Please file bugs @ https://testssl.sh/bugs/

###########################################################

 Using "OpenSSL 1.0.2-chacha (1.0.2k-dev)" [~183 ciphers]
 on neth-test:./bin/openssl.Linux.x86_64
 (built: "Jan 18 17:12:17 2019", platform: "linux-x86_64")


 Start 2020-04-17 16:22:51        -->> 192.168.1.26:443 (heimdall.familybrown.org) <<--

 rDNS (192.168.1.26):    heimdall.familybrown.org.
 Service detected:       HTTP


 Testing protocols via sockets except NPN+ALPN 

 SSLv2      not offered (OK)
 SSLv3      not offered (OK)
 TLS 1      not offered
 TLS 1.1    not offered
 TLS 1.2    offered (OK)
 TLS 1.3    offered (OK): final
 NPN/SPDY   h2, http/1.1, acme-tls/1 (advertised)
 ALPN/HTTP2 h2, http/1.1 (offered)

 Testing cipher categories 

 NULL ciphers (no encryption)                       not offered (OK)
 Anonymous NULL Ciphers (no authentication)         not offered (OK)
 Export ciphers (w/o ADH+NULL)                      not offered (OK)
 LOW: 64 Bit + DES, RC[2,4], MD5 (w/o export)       not offered (OK)
 Triple DES Ciphers / IDEA                          not offered
 Obsolete: SEED + 128+256 Bit CBC cipher            not offered
 non-FS Strong encryption (AEAD ciphers)            not offered
 Forward Secure Strong encryption (AEAD ciphers)    offered (OK)


 Testing robust forward secrecy (FS) -- omitting Null Authentication/Encryption, 3DES, RC4 

 FS is offered (OK)           TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-ECDSA-AES256-GCM-SHA384
                              ECDHE-ECDSA-CHACHA20-POLY1305 TLS_AES_128_GCM_SHA256 ECDHE-ECDSA-AES128-GCM-SHA256 
 Elliptic curves offered:     prime256v1 X25519 


 Testing server preferences 

 Has server cipher order?     yes (OK) -- TLS 1.3 and below
 Negotiated protocol          TLSv1.3
 Negotiated cipher            TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Cipher order
    TLSv1.2:   ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 ECDHE-ECDSA-CHACHA20-POLY1305 
    TLSv1.3:   TLS_AES_128_GCM_SHA256 TLS_CHACHA20_POLY1305_SHA256 TLS_AES_256_GCM_SHA384 


 Testing server defaults (Server Hello) 

 TLS extensions (standard)    "next protocol/#13172" "status request/#5" "session ticket/#35" "renegotiation info/#65281"
                              "supported versions/#43" "key share/#51" "application layer protocol negotiation/#16"
 Session Ticket RFC 5077 hint no -- no lifetime advertised
 SSL Session ID support       yes
 Session Resumption           Tickets no, ID: no
 TLS clock skew               Random values, no fingerprinting possible 
 Signature Algorithm          SHA256 with RSA
 Server key size              EC 256 bits
 Server key usage             Digital Signature
 Server extended key usage    TLS Web Server Authentication, TLS Web Client Authentication
 Serial / Fingerprints        04357215BFAB2267152D819C172897159D97 / SHA1 E37EF14B26C2A8BEFF3C49F2F0377187C8A41EC9
                              SHA256 71CAD194F6B81B3E3EF35D2CDCF3A4211EB2E5EF01C52E95F4ECEE3CC1FE6BF0
 Common Name (CN)             heimdall.familybrown.org  (request w/o SNI didn't succeed)
 subjectAltName (SAN)         heimdall.familybrown.org 
 Issuer                       Let's Encrypt Authority X3 (Let's Encrypt from US)
 Trust (hostname)             Ok via SAN (SNI mandatory)
 Chain of trust               Ok   
 EV cert (experimental)       no 
 ETS/"eTLS", visibility info  not present
 Certificate Validity (UTC)   81 >= 30 days (2020-04-08 21:21 --> 2020-07-07 21:21)
 # of certificates provided   2
 Certificate Revocation List  --
 OCSP URI                     http://ocsp.int-x3.letsencrypt.org
 OCSP stapling                offered, not revoked
 OCSP must staple extension   --
 DNS CAA RR (experimental)    available - please check for match with "Issuer" above
                              issue=comodoca.com, issue=digicert.com, issue=letsencrypt.org, issuewild=comodoca.com,
                              issuewild=digicert.com, issuewild=letsencrypt.org
 Certificate Transparency     yes (certificate extension)


 Testing HTTP header response @ "/" 

 HTTP Status Code             200 OK
 HTTP clock skew              0 sec from localtime
 Strict Transport Security    not offered
 Public Key Pinning           --
 Server banner                Caddy
 Application banner           X-Powered-By: PHP/7.2.24
 Cookie(s)                    2 issued: NONE secure, 1/2 HttpOnly
 Security headers             Cache-Control no-cache, private
 Reverse Proxy banner         --


 Testing vulnerabilities 

 Heartbleed (CVE-2014-0160)                not vulnerable (OK), no heartbeat extension
 CCS (CVE-2014-0224)                       not vulnerable (OK)
 Ticketbleed (CVE-2016-9244), experiment.  not vulnerable (OK), no session tickets
 ROBOT                                     Server does not support any cipher suites that use RSA key transport
 Secure Renegotiation (RFC 5746)           OpenSSL handshake didn't succeed
 Secure Client-Initiated Renegotiation     not vulnerable (OK)
 CRIME, TLS (CVE-2012-4929)                not vulnerable (OK)
 BREACH (CVE-2013-3587)                    potentially NOT ok, uses gzip HTTP compression. - only supplied "/" tested
                                           Can be ignored for static pages or if no secrets in the page
 POODLE, SSL (CVE-2014-3566)               not vulnerable (OK), no SSLv3 support
 TLS_FALLBACK_SCSV (RFC 7507)              No fallback possible (OK), no protocol below TLS 1.2 offered
 SWEET32 (CVE-2016-2183, CVE-2016-6329)    not vulnerable (OK)
 FREAK (CVE-2015-0204)                     not vulnerable (OK)
 DROWN (CVE-2016-0800, CVE-2016-0703)      not vulnerable on this host and port (OK)
                                           no RSA certificate, thus certificate can't be used with SSLv2 elsewhere
 LOGJAM (CVE-2015-4000), experimental      not vulnerable (OK): no DH EXPORT ciphers, no DH key detected with <= TLS 1.2
 BEAST (CVE-2011-3389)                     not vulnerable (OK), no SSL3 or TLS1
 LUCKY13 (CVE-2013-0169), experimental     not vulnerable (OK)
 RC4 (CVE-2013-2566, CVE-2015-2808)        no RC4 ciphers detected (OK)


 Testing 370 ciphers via OpenSSL plus sockets against the server, ordered by encryption strength 

Hexcode  Cipher Suite Name (OpenSSL)       KeyExch.   Encryption  Bits     Cipher Suite Name (IANA/RFC)
-----------------------------------------------------------------------------------------------------------------------------
 x1302   TLS_AES_256_GCM_SHA384            ECDH 253   AESGCM      256      TLS_AES_256_GCM_SHA384                             
 x1303   TLS_CHACHA20_POLY1305_SHA256      ECDH 253   ChaCha20    256      TLS_CHACHA20_POLY1305_SHA256                       
 xc02c   ECDHE-ECDSA-AES256-GCM-SHA384     ECDH 256   AESGCM      256      TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384            
 xcca9   ECDHE-ECDSA-CHACHA20-POLY1305     ECDH 253   ChaCha20    256      TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256      
 x1301   TLS_AES_128_GCM_SHA256            ECDH 253   AESGCM      128      TLS_AES_128_GCM_SHA256                             
 xc02b   ECDHE-ECDSA-AES128-GCM-SHA256     ECDH 256   AESGCM      128      TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256            


 Running client simulations (HTTP) via sockets 

 Android 4.4.2                TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Android 5.0.0                TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 6.0                  TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256, 256 bit ECDH (P-256)
 Android 7.0                  TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 253 bit ECDH (X25519)
 Android 8.1 (native)         TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 253 bit ECDH (X25519)
 Android 9.0 (native)         TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Android 10.0 (native)        TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Chrome 74 (Win 10)           TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Chrome 79 (Win 10)           TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Firefox 66 (Win 8.1/10)      TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Firefox 71 (Win 10)          TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 IE 6 XP                      No connection
 IE 8 Win 7                   No connection
 IE 8 XP                      No connection
 IE 11 Win 7                  TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 IE 11 Win 8.1                TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 IE 11 Win Phone 8.1          TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 IE 11 Win 10                 TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Edge 15 Win 10               TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 253 bit ECDH (X25519)
 Edge 17 (Win 10)             TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 253 bit ECDH (X25519)
 Opera 66 (Win 10)            TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Safari 9 iOS 9               TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Safari 9 OS X 10.11          TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Safari 10 OS X 10.12         TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Safari 12.1 (iOS 12.2)       TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Safari 13.0 (macOS 10.14.6)  TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Apple ATS 9 iOS 9            TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Java 6u45                    No connection
 Java 7u25                    No connection
 Java 8u161                   TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 Java 11.0.2 (OpenJDK)        TLSv1.3 TLS_AES_128_GCM_SHA256, 256 bit ECDH (P-256)
 Java 12.0.1 (OpenJDK)        TLSv1.3 TLS_AES_128_GCM_SHA256, 256 bit ECDH (P-256)
 OpenSSL 1.0.2e               TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 256 bit ECDH (P-256)
 OpenSSL 1.1.0l (Debian)      TLSv1.2 ECDHE-ECDSA-AES256-GCM-SHA384, 253 bit ECDH (X25519)
 OpenSSL 1.1.1d (Debian)      TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)
 Thunderbird (68.3)           TLSv1.3 TLS_AES_128_GCM_SHA256, 253 bit ECDH (X25519)

 Done 2020-04-17 16:23:56 [  69s] -->> 192.168.1.26:443 (heimdall.familybrown.org) <<--

 
Joined
Jan 4, 2014
Messages
1,644

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
I know this should be obvious based on the instructions, but I need to clarify a few concepts.
1) If you want to access any of the jails behind a reverse proxy(RP) from the internet the RP must be configured with port 80 and 443 forwarded to your RP jail?
2) DNS Validation is only if you don't want to expose the RP to the internet but still want to use https in your internal network?
3) Can you run 2 RP one for servers connected to the internet like nextcloud and wordpress and another only on the internal network for sabnzb, plex etc?
4) "You must own or control a live Internet domain (or subdomain)--I'll use sub.example.com" Can you use a RP like this if you have a freenom domain and clouldflare DNS or do you have to purchase a domain to use from the internet?
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
1) If you want to access any of the jails behind a reverse proxy(RP) from the internet the RP must be configured with port 80 and 443 forwarded to your RP jail?
Correct.
DNS Validation is only if you don't want to expose the RP to the internet but still want to use https in your internal network?
You could use it even if the RP were accessible to the Internet, but I'm not sure there's a good reason to.
Can you run 2 RP one for servers connected to the internet like nextcloud and wordpress and another only on the internal network for sabnzb, plex etc?
I don't see any reason you couldn't.
Can you use a RP like this if you have a freenom domain and clouldflare DNS or do you have to purchase a domain to use from the internet?
As long as you control the (sub)domain, it doesn't matter how--whether you bought it, registered it for free with freenom, or were given it by a dynamic DNS provider is irrelevant.
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
I have a working Nextcloud instance with dan's script (works great), with ports 80/443 open on my router to the jail. I'm trying to create an internal reverse proxy per this resource. I have a cloudflare account that says mydomain.cf is active and my freenom dns is set to the dns servers that cloudflare supplies.

I want to take this one step at a time and get the basic setup working before adding multiple proxies. I hope someone can find the issue.

My sample index.html file is in place.

My /etc/rc.conf
Code:
caddy_cert_email: myemail@gmail.com
caddy_enable: YES
caddy_env: CLOUDFLARE_EMAIL=myemail@gmail.com CLOUDFLARE_API_KEY=**************************
cron_flags:  -J 15
hostname: caddy
ipv6_activate_all_interfaces: YES
sendmail_enable: NO
sendmail_msp_queue_enable: NO
sendmail_outbound_enable: NO
sendmail_submit_enable: NO
syslogd_flags: -c -ss


My Caddyfile
Code:
mydomain.cf 192.168.5.82:80 {

        root   /usr/local/www/html/

tls {
        dns cloudflare
}
gzip

}


My cloudflare DNS page
Cloudflare DNS.jpg


My caddy.log
Code:
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: Obtaining bundled SAN certificate
2020/04/20 21:01:43 [INFO] [mydomain.cf] AuthURL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/111111111
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: Could not find solver for: tls-alpn-01
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: Could not find solver for: http-01
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: use dns-01 solver
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: Preparing to solve DNS-01
2020/04/20 21:01:43 [INFO] [mydomain.cf] acme: Cleaning DNS-01 challenge
2020/04/20 21:01:44 [WARN] [mydomain.cf] acme: error cleaning up: cloudflare: failed to find zone cf.: Zone could not be found
2020/04/20 21:01:44 [INFO] Deactivating auth: https://acme-v02.api.letsencrypt.org/acme/authz-v3/1111111111
2020/04/20 21:01:44 [ERROR][mydomain.cf] failed to obtain certificate: acme: Error -> One or more domains had a problem:
[mydomain.cf] [mydomain.cf] acme: error presenting token: cloudflare: failed to find zone cf.: Zone could not be found (attempt 3/3; challenge=dns-01)
2020/04/20 21:01:45 failed to obtain certificate: acme: Error -> One or more domains had a problem:
[mydomain.cf] [mydomain.cf] acme: error presenting token: cloudflare: failed to find zone cf.: Zone could not be found
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
mydomain.cf 192.168.5.82:80 {
This wouldn't really explain the errors you're seeing in the log, but try taking out the ip:port--even if that isn't what's causing the problem, it's likely to confuse things.
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
I removed it and just have mydomain.cf { and still get the same log entries after a service caddy restart
 
Joined
Jan 4, 2014
Messages
1,644
Are ports 80/443 forwarded to your Caddy jail or your Nextcloud jail?
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
My nextcloud jail not the caddy jail. I thought the concept of the DNS option was if you don’t want to open 80/443 to the jail.
 

danb35

Hall of Famer
Joined
Aug 16, 2011
Messages
15,504
I thought the concept of the DNS option was if you don’t want to open 80/443 to the jail.
Certainly it can work without those ports being forwarded to the jail. Are you sure the Cloudflare email/API key you've entered correspond to the account that's providing DNS for that domain?
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
Yes it's the correct email and the API key is the "Global API Key"
 
Joined
Jan 4, 2014
Messages
1,644
My /etc/rc.conf
Code:
caddy_cert_email: myemail@gmail.com
caddy_enable: YES
caddy_env: CLOUDFLARE_EMAIL=myemail@gmail.com CLOUDFLARE_API_KEY=**************************
cron_flags: -J 15
hostname: caddy
ipv6_activate_all_interfaces: YES
sendmail_enable: NO
sendmail_msp_queue_enable: NO
sendmail_outbound_enable: NO
sendmail_submit_enable: NO
syslogd_flags: -c -ss
Why is my rc.conf formatted differently to yours? Does it matter? For instance:
caddy_env="CLOUDFLARE_EMAIL=myemail@gmail.com CLOUDFLARE_API_KEY=**************************"
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
Why is my rc.conf formatted differently to yours? Does it matter? For instance:
caddy_env="CLOUDFLARE_EMAIL=myemail@gmail.com CLOUDFLARE_API_KEY=**************************"
Good pick up but it doesn't matter. My original was the output from sysrc -a. When I cat /etc/rc.conf I get the same format as you.

I'm using pfsense and have pfBlockerNG to protect ports 80/443 that are open. Just in case I turned it off but it made no difference.
Tried creating a Zone.DNS and used their curl command to verify it was working. Then put it into the rc.conf file. Still no go.

Went back to the global API and tried it with the (......) got an error message "Syntax error: "(" unexpected" so I went back to original.
Tried to redo the DNS steps
1) pkg lock caddy
2) curl https://getcaddy.com | bash -s personal tls.dns.cloudflare but it fails to connect and the operation times out
I can ping www.google.com from the jail.

Maybe I should ditch the DNS option and foward 80/443 to the caddy jail. Could I convert my working nextcloud to work or would I have to start the nextcloud script with the NO_CERT option?


 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
Original I made a script to install caddy. Decided to try it manually. Destroyed the jail and started over. When I get to the curl step it does operation timed out. Maybe that is the problem the plugin doesn't download.
 
Top