When you want to bypass the firewall without exposing the domain name bound to that IP

Let’s Encrypt officially supports issuing certificates for IP addresses.

However, current Caddy support is not great.

But you can use acme.sh to automatically issue certificates for Caddy

First, stop all software occupying ports 80/443, install socat, and manually issue a certificate with acme.sh in standalone mode:

acme.sh --issue \
-d =YOURIP= \
--standalone \
--server letsencrypt \
--certificate-profile shortlived \
--days 3

Then configure Caddy:

mkdir -p /etc/caddy/certs
chown caddy:caddy /etc/caddy/certs
chmod 700 /etc/caddy/certs

/etc/caddy/Caddyfile:

{
        auto_https off
        servers {
                protocols h1 h2
        }
        order forward_proxy before file_server
}
:80 {
        handle /.well-known/acme-challenge/* {
                root * /var/www/letsencrypt
                file_server
        }

        handle {
                redir https://{host}{uri} permanent
        }
}

:443 {
        tls /etc/caddy/certs/fullchain.pem /etc/caddy/certs/key.pem {
                protocols tls1.2 tls1.3
        }
        forward_proxy {
                basic_auth ussername password
                hide_ip
                hide_via
                probe_resistance
        }

        respond "OK"
}

Next, install the certificate to the specified location with acme.sh:

acme.sh --install-cert \
  -d =YOURIP= \
  --cert-file /etc/caddy/certs/cert.pem \
  --key-file /etc/caddy/certs/key.pem \
  --fullchain-file /etc/caddy/certs/fullchain.pem \
  --reloadcmd "chown caddy:caddy -R /etc/caddy/certs; systemctl reload cd "

Restart Caddy, then configure acme.sh to automatically issue certificates in the future using the webroot method:

acme.sh --issue --server letsencrypt \
  -d =YOURIP= \
  -w /var/www/letsencrypt \
  --certificate-profile shortlived \
  --days 3

After these steps, you should theoretically be able to bypass censorship via TCP (using naiveproxy).
You need to compile Caddy with the forwardproxy module using xcaddy:

~/go/bin/xcaddy build --with github.com/caddyserver/forwardproxy=github.com/klzgrad/forwardproxy@naive

Of course, UDP performance is higher (using tuic). See tuic/tuic-server at main · Itsusinn/tuic · GitHub for installation and configuration:

cargo install --git https://github.com/Itsusinn/tuic.git tuic-server
tuic-server --init

In config.toml, modify the following sections:

server = "[::]:443"
data_dir = "/etc/tuics"
[users]
self_sign = false
certificate = "/etc/caddy/certs/fullchain.pem"
private_key = "/etc/caddy/certs/key.pem"
alpn = ["h3"]
hostname = "=YOURIP="
auto_ssl = false
1 Like

TIL, I’ve been researching this recently.