Caddy 是一个使用 Go 编写的 Web 服务器,它具有自动 HTTPS 和配置简单的特点,我的网站使用的也是 Caddy。

注意,我这里使用的 Caddy 是 Caddy2,也是 Caddy 现在的主要版本,之前的 Caddy1 和以后的 Caddy3 不保证能使用!

basicauth 身份验证

如果你的网站不想随便让其他人访问,你可能会考虑给网站加入一个身份验证之类的。身份验证最常见的方式就是使用账号和密码,但是如果你的网站是静态网页或者你不太了解编程的话,就可能不太方便了。

basicauth 基本身份验证是 HTTP 的一种身份验证方式,在发送 HTTP 请求时,需要在请求头通过 Authorization 字段来传递账号和密码。

如果你使用标准浏览器访问包含 basicauth 验证的网站时,会弹出一个对话框来输入账号和密码,输入正确才能继续访问。身份验证成功后,只要不重启浏览器就不需要再次手动输入账号密码验证。

basicauth 可以直接给整个网站设置,也可以给指定的目录设置。

生成密码

Caddy 的 basicauth 密码不能直接在配置文件中填写明文密码,需要使用哈希算法加密后填写,Caddy 也提供了一个 caddy hash-password 命令来生成密码。

caddy hash-password 包含 -p 密码和 -a 算法两个参数,-a 算法只支持 bcrypt,默认也是 bcrypt,所以 -a 参数可以省略。

下面使用 misterma.com 作为密码来生成一个密码:

caddy hash-password -p "misterma.com"

生成的值是 $2a$14$6F6gIyTSw871Ru8mN7zTh..IdqBBaY5W/OFrAo7nuR4CzuSttXBZq

配置 basicauth 验证

我下面使用的配置格式是 Caddyfile,不是 JSON,下面配置全站启用账号和密码:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 配置身份验证
    basicauth /* {
        123456 $2a$14$B2s37ArzMiwornXEZNx8u.08hyjtkY4oZRH63kmhANwqEHc/aS9RO
    }
}

上面的 basicauth 后面的 /* 就是从根目录开始,所有路径都需要输入账号和密码,123456 就是账号,$2a$14$B2s37ArzMiwornXEZNx8u.08hyjtkY4oZRH63kmhANwqEHc/aS9RO 就是密码。

如果需要配置多个账号和密码可以在 basicauth 内配置多行,一行一个账号和密码,如下:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 配置身份验证
    basicauth /* {
        user1 $2a$14$vD5FQZio1w0i52KtgJvPuOlFtfPCqw1PQ.fOJmY3dZzHG6di.ERVq
        user2 $2a$14$vr6csmQc8Dk/Bj3JqMsdhOjISjWUQ3P0URUykOnoc1EaGxdBPkXka
    }
}

你也可以给不同的目录配置不同的账号和密码,如下:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 配置身份验证
    basicauth /user1/* {
        user1 $2a$14$vD5FQZio1w0i52KtgJvPuOlFtfPCqw1PQ.fOJmY3dZzHG6di.ERVq
    }
    basicauth /user2/* {
        user2 $2a$14$vr6csmQc8Dk/Bj3JqMsdhOjISjWUQ3P0URUykOnoc1EaGxdBPkXka
    }
}

禁止指定 IP 访问

Caddyfile 的 @blocked_ip 可以配置禁止指定 IP 访问,你可以对指定的 IP 返回指定的状态码和内容,如下:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 禁止指定 IP 访问
    @blocked_ip {
        remote_ip 127.0.0.1
    }
    respond @blocked_ip "Forbidden" 403
}

上面如果是 127.0.0.1 的用户访问就会返回 403 Forbidden。

上面的 Forbidden 你也可以换成其它内容,你甚至可以重定向或其它操作,下面把 127.0.0.1 重定向到 misterma.com:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 对指定 IP 重定向
    @blocked_ip {
        remote_ip 127.0.0.1
    }
    redir @blocked_ip https://misterma.com
}

上面如果是 127.0.0.1 访问就会被重定向到 misterma.com。

如果需要配置多个 IP 可以这样配置:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 禁止多个 IP 访问
    @blocked_ip {
        remote_ip 127.0.0.1 192.168.2.156
    }
    respond @blocked_ip "Forbidden" 403
}

多个 IP 之间用空格分隔,上面配置了 127.0.0.1 和 192.168.2.156。

禁止指定 IP 段访问

Caddy 匹配 IP 段需要使用 CIDR 表示法来匹配,关于 CIDR 的计算可以在 Google 上搜索 CIDR计算器来计算。

下面禁止 192.168 开头的 IP 访问:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 禁止指定 IP 访问
    @blocked_ip {
        remote_ip 192.168.0.0/16
    }
    respond @blocked_ip "Forbidden" 403
}

上面的 192.168.0.0/8 包含了从 192.168.0.0 到 192.168.255.255 的 65536 个 IP。

禁止指定 User agent 的客户端访问

浏览器在发送请求的时候会带上一组 User agent,User agent 包含了浏览器的标识和操作系统信息。

注意!浏览器的 User agent 是可以更改的,有些浏览器可以通过更改 User agent 来伪装成其它浏览器,爬虫之类的也可以设置 User agent 来伪装成浏览器。

浏览器的 User agent 在更新版本的时候也会变化,建议使用正则表达式来匹配,下面匹配包含 iPhone 的 UA:

http://:80 {
    # 网站目录
    root * /www/web
    # 启用静态文件服务和文件目录显示
    file_server browse
    # 禁止指定 UA 访问
    @blocked_useragents {
        header_regexp blocked User-Agent iPhone|iphone
    }
    respond @blocked_useragents "Forbidden" 403
}

上面匹配了 iPhoneiphone,只要 UA 中出现这两个词就返回 403。

你也可以使用 @blocked_useragents 来匹配特定的 UA,根据 UA 来进行重定向之类的操作,比如 App 下载页面可以根据操作系统 UA 来提供指定平台的 App,网站也可以根据 UA 来选择提供 PC 或移动版网站。

类似文章: