Total Pageviews

Saturday, 25 November 2017

Setting up Caddy Server on Debian

Caddy Server looks like is the next-gen web server. Here are some specs about Caddy that might be relevant :
  • HTTP/2 & HTTP
  • IPv6 & IPv4
  • Out of the Box Let's Encrypt support
  • Markdown
  • Websockets
  • Proxy and load balancer
  • FastCGI
  • Overly simple configuration files
  • ... And a lot more !
For a complete list of directives that Caddy supports you can head to the official documentation

Let's Encrypt Integration

As of version 0.8 of Caddy, it is now integrating Let's Encrypt. See Caddy 0.8 Released with Let's Encrypt Integration on the Caddy Blog.
Why is that such a big deal ? What does it mean ? Let's Encrypt could be the subject of a whole blog post. In short terms it allows you to receive and use free SSL certificates and thus allows anyone to provide a secure layer to their website. For a long time, having a valid (signed everywhere) certificate was complicated and expensive. Meaning : If you wanted to provide a security layer to your website you had to pay. And not only you had to pay, but you were also compelled to prove that you're actually the owner of your domain by giving lot of information about yourself. Let's Encrypt breaks this wall. It brings security to any site owner, even those without the funds to pay for a valid certificate. It's the end of the x509 certificate era.
Now what does Caddy have to do with that ? Well Caddy... Automatically serves your sites with HTTPS by using Let's Encrypt. You don't have to do anything, you don't have to worry about the certificates. You don't even have to give out any personal information about yourself. It just abstracts the process of requesting a certificate and using it. It also abstracts the renewal of these certificates. Meaning that with a two line long configuration file like this :
depado.eu {
    proxy / localhost:8080
}
It will automatically request Let's Encrypt for a valid certificate and serve depado.eu with HTTPS by default. Isn't that just great ? To get more information about that feature of caddy, head over to the documentation about automatic https.

Installation

First of all, go to the Caddy Server Download Page and select the features you want, your architecture and operating system. Instead of click on the button, right click and copy the url. Time to ssh into your server and start having fun. First of all, let's download caddy in a relevant location.
# mkdir /etc/caddy/
# wget "https://caddyserver.com/download/build?os=linux&arch=amd64&features=" /etc/caddy/caddy.tar.gz
# tar xvf /etc/caddy/caddy.tar.gz
You can give Caddy the rights to bind to low ports. To do so, here is the command you can execute :
# setcap cap_net_bind_service=+ep /etc/caddy/caddy
Let's create our first Caddyfile in /etc/caddy/. Edit /etc/caddy/Caddyfile and add something like that :
yourdomain.com {
    proxy / localhost:5000
}
Assuming something is running on port 5000, Caddy will then proxy every request for the yourdomain.com domain directly to the application running on that port. If you already have a website you want to bind to caddy, then head over to the full documentation and see what directives are useful for you. Let's start caddy for the first time so that it can bind itself to Let'sEncrypt service.
# cd /etc/caddy/
# ./caddy
Caddy will then ask you for an email to give to the Let'sEncrypt service. If you don't wish to give that out, then don't, but keep in mind that you won't be able to recover your keys if you loose them. Our initial setup is done. Let's move on to the supervisor section.

Supervisor configuration

In this guide I'll assume you have a functionning supervisor installation. It will allow us to execute caddy as a daemon. First of all we'll edit the /etc/supervisor/supervisord.conf and add this line under the [supervisord] section :
minfds=4096
Why is that ? In a production environment, caddy will complain that the number of open file descriptor is too low. The reason is that supervisor's default value is too low (1024, instead of 4096 as recommended by caddy). Now let's add a new program to our supervisor configuration. Create the file /etc/supervisord/conf.d/caddy.conf:
[program:caddy]
directory=/etc/caddy/
command=/etc/caddy/caddy -conf="/etc/caddy/Caddyfile"
user=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/caddy_stdout.log
stderr_logfile=/var/log/supervisor/caddy_stderr.log
You can customize the user to the one you want. As I said earlier, caddy now doesn't need root privileges to bind to low ports, so any user will do (prefer a user with few rights). Caddy is now ready to be started by supervisor ! Simply add the program into supervisor and enjoy.
# supervisorctl reread
# supervisorctl add caddy
# supervisorctl start caddy
from http://depado.markdownblog.com/2015-12-07-setting-up-caddy-server-on-debian
相关帖子:http://briteming.blogspot.com/2017/11/caddyhttp2-proxy.html
------------------

Caddy – 最简单的支持 HTTP/2 的网页服务器[Win/Mac/Linux]

Caddy是一款使用Go语言的简单易用的单文件网页服务器,原生支持HTTP/2,自动创建
Let’s Encrypt证书,支持反代、rewrite、git、REST API、ipfilter、jsonp等,
非常适合各种轻量级的网页应用,或者在本地电脑使用,无论是静态HTML、图片,或者是
WordPress、Drupal、Markdown,统统都支持。 Caddy存在的意义在于不需要繁琐的编译 Nginx、Apache,只需要运行Caddy就完成了
HTTP 服务器的搭建.如果你有自己的域名,还能自动配置Let’s Encrypt,实现
HTTPS加密,使用的是HTTP/2协议。
只需要在 Caddy 的目录下创建 Caddyfile 文件,里面写上域名就行了… 最简单的教程: 下载 Caddy 在 Caddy 目录放置 index.html 文件 打开浏览器,输入 127.0.0.1:2015 如果你是一个网页设计师,那 Caddy 比那些一键安装包要方便多了;
如果想在 VPS 搭建一个静态服务器,用 Caddy 比 Nginx 更加简便。 而如果你想更换端口、开启日志、开启 git、markdown 之类的,
就需要配置下Caddyfile 文件了。 比如,你可以让 Caddy 定期去 git pull 项目库,让其自动更新,
你只需要管好 git 就行了。你也可以直接写 Markdown,Caddy自动帮你渲染成HTML… 呃,其实这篇文章不是一篇教程,只是一篇介绍文字,如果你想有更复杂的功能,需要去
研究 Caddy 文档,就技术门外汉来看,
入门不难,至少比 Nginx 简单多了。
下载地址: https://caddyserver.com/download
https://getcaddy.com/
-----------

轻松把文件夹变成网站!使用 Caddy 服务器软件自己搭建网页形式的文件共享

随着网盘陆续的关闭,各种承诺的破灭,让很多人开始重新考虑将重要文件搬回到自己的电脑上了。不过,
保存在个人电脑上的文件想要分享始终不是很便利。 今天我们介绍的是一种另类的网页式文件共享方式,使用 Caddy 服务器软件!轻松将自己的电脑变成服务器,
搭建一个属于自己的“网站”,从而将文件夹以网页的形式共享出去,让局域网甚至互联网上的其他电脑、
手机、平板设备均能通过浏览器轻松访问和下载它们…… 什么是 Caddy? Caddy 实际上是一款免费开源的 WEB 服务器软件,可以让用户非常简单地在电脑上搭建出一个网站。
它的特点是配置简单,入门容易,稍微研究下即能将自己的文件部署到局域网或互联网上,
共享给其他设备通过浏览器进行访问。 虽说看起来 Caddy 似乎很高端的样子 (至少搭建网站服务器什么的对非专业人士确实有点难度),
但是 Caddy 本身是一个以「易用」为目标而开发的软件,使用它仅仅需要通过编写简单的“配置文件”即可,
比起那些要用脚本和专业知识才能玩得转的服务器程序,Caddy 的门槛是大大降低了。
对于想尝试自己搭建网页服务器而又没有太多基础的朋友应该说是很具有可玩性的。 Caddy 的功能和模块很多,在这篇文章里我们主要介绍利用 Caddy 内置的文件管理器模块,
实现方便的互联网/局域网文件共享功能,其他的各种更加“专业”的服务器功能和玩法就留待大家自己去研究了。 为了方便读者“入门”,下面我们先介绍一下它的基本使用, 关于“文件管理器模块”的介绍在放在后半段。
Caddy 本身支持 macOS 和 Linux 系统,但本文主要介绍在 Windows 系统下的用法。 Caddy 基本使用 - 搭建基础网站 1. Caddy 的使用非常简单,首先下载 Caddy 软件(下载时需要选择你想要安装的模块,看“注意2”,
本文主要介绍它的 filemanager 模块),并解压到任意目录下。 2. 进入到此文件夹内,在此根目录新建一个“index.html” (首页) 文件,用记事本编辑,
输入任何内容如 “Hello Caddy!” 并保存。 3. 接着双击 Caddy 程序启动,此时在本机的游览器中输入 “localhost:2015”
即可看到 “index.html” 文件中的内容。 注意 1:因为 index.html 文件是网页的首页,Caddy 会自动识别.
如果文件名改成 “another.html”,就必须输入 “localhost:2015/another.html” 才能看到了。 注意 2:如果之后要使用 “filemanager 文件管理器” 等模块,
那么在下载的时候必须要手动勾选对应的模块,默认只勾选了核心模块。 把网址设置为电脑的局域网 IP 上面用 localhost 作为地址可以让本机访问,而如果你希望这个“网站”可以让局域网甚至是互联网上的
其他设备访问,那么就需要为其设置正确的网址域名或 IP 地址了。为简单起见,
我们本教程只以「局域网访问」为例子,如果你需要互联网访问,还得自行去了解 DDNS 动态域名
(比如花生壳)、路由器的端口映射设置等概念。 设置正确的 IP 地址或域名是实现局域网文件共享的前提。本操作分为两步: 首先要获得你的电脑在局域网内的 IP。 将这个 IP 地址写入 Caddy 的特定配置文件里。 Windows 系统下获取本机的局域网 IP 地址的方式为在命令行界面输入“ipconfig”命令并回车。
一般都是类似“192.168.X.XXX”的形式。值得注意的是,大多数路由器默认情况下都是通过DHCP动态,
给设备分配 IP 地址的,每次路由器重启后,你的电脑 IP 地址可能都会变,
因此最好在路由器的设置界面为电脑设置固定的 IP。 在 Caddy 目录下新建一个名为 “Caddyfile” 的配置文件(没有扩展名),用记事本打开,
在里面输入你的电脑的局域网 IP 地址(或者域名)+英文冒号+端口号。重启 Caddy程序后,
就能用任意局域网内的其他设备访问这个地址了。这也为我们的“局域网内共享文件”做好了准备。 如果需要通过互联网访问,那么这里的 IP就要修改成你的公网 IP 或者动态域名了。
我这里还是以局域网为例子,对于的网址是 192.168.0.105:2016,从连着家里 WiFi 的手机上访问的
结果如下. 接下来是我们的重点:从局域网内共享内容(文字,图片等) 我们在下载安装 Caddy 时已经选择了「文件管理」模块 “filemanager”,
只需要在之前提到的 “Caddyfile” 中写入正确的配置,即可使用Caddy内置的文件管理器
在局域网或互联网上共享文件。
192.168.0.105:2016 filemanager /file { show allow_new allow_edit ./file true true } 比如像上面的配置代码(show 参数用来设置文件在电脑上对应的路径, allow_new、allow_edit
表示允许新建和修改),而 ./file 是文件夹的路径,你可以修改成其他路径。更多的配置说明,
可以参考文档- https://caddyserver.com/docs/caddyfile 在 Caddy 目录下新建一个“file”文件夹,在里面放入一些文件,再次重启 Caddy。 结语 因为 Caddy 的 “文件管理器” 内建支持新建文件和修改(修改应该只支持纯文本格式),
以及文件的下载和上传,相比常见的服务器软件比如 Nginx、Apache 等更能满足一般用户的文件共享需求,
比如: 在电脑端放入一个“.apk”文件,即可在 Android 设备下载并安装。 在手机端黏贴一段文本到一个文本文件中,即可在电脑端处理。 在手机端上传一张图片,即可在电脑端得到这张图片。 通过上传下载功能可以实现少量文件的拷贝等。 Caddy 可以在配置中设置任意的文件夹为共享文件夹,比较灵活。而且你不需要在手机端安装任何软件,
只需通过游览器访问即可。缺点是功能比较单一,在丰富性上显然无法与专门的软件相比。
不过在一些轻量级的使用场景,无论是自用还是与家人、同事使用还是比较方便的。 另外 Caddy 还有更多的功能,比如支持 “Markdown” 语法解析等。有兴趣的朋友可以在阅读官方文档-
https://caddyserver.com/docs进行了解.
--------------------------

Caddy 服务器

这是一个Web Server的时代,apachenginx共舞,在追求极致性能的路上,没有最高,只有更高。但这又是一个追求个性化的时代,有些Web Server并没有去挤“Performance提升”这一独木桥,而是有着自己的定位,Caddy就是这样一个开源Web Server。
Caddy的作者Matt Holt在caddy官网以及FAQ中对caddy的目标阐释如下: 其他Web Server为Web而设计,Caddy为human设计。功能定位上,与经常充当最前端反向代理的nginx不同,caddy致力于成为一个易用的静态文件Web Server。可以看出Caddy主打易用性,使用配置简单。并且得益于Go的跨平台特性,caddy很容易的支持了三大主流平台:Windows、 Linux、Mac。在Caddy开发者文档中,我们可以看到caddy还可以在Android(linux arm)上运行。caddy目前版本为0.7.1,还不稳定,且后续版本可能变化较大,甚至与前期版本不兼容,因此作者目前不推荐caddy在生产环境被 重度使用。
Caddy 是一个支持 HTTP/2 的跨平台 Web 服务器,使用和配置都非常简单。Caddy 支持 HTTP/2, IPv6, Markdown, WebSockets, FastCGI, 模板等等。
One-step installer script (bash):
curlhttps://getcaddy.com | bash

配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#=> Caddyfile配置 https://caddyserver.com/docs/caddyfile
##########################
# 多站点 #
##########################
#=> Vue2.0站点 → port:2000
localhost:2000,
http://vue-2-demo.com {
# 站点物理路径
root ../../../Users/lxbin/Documents/WWW/vue-2.0-demo/dist
# log日志输出路径
#log ../log/localhost-2000.log
# 开启gzip
#gzip
}
#=> 9X_WAP站点 → port:8000
localhost:8000,
http://m2.test.jiuxiulvxing.com {
# 站点物理路径
root ../../../Users/lxbin/Documents/WWW/9X_WAP/
# log日志输出路径
log ../log/localhost-8000.log
# 开启gzip
#gzip
}
##########################
# 反向代理 #
##########################
#=> 反向代理 → port:80
#http://leo.xuebin.leo {
# proxy / localhost:80
# log ../log/proxy-port-80.log
#}
#=> 反向代理 → port:8080
#http://leo.xuebin.leo {
# proxy / localhost:8080
# log ../log/proxy-port-8080.log
#}
#http://leo.xuebin.leo {
# proxy / localhost:8000
# log ../log/proxy-port-8000.log
#}
##########################
# 文件服务器 #
##########################
#=> 文件服务器,指定文件服务器地址
192.168.100.126:1000
filemanager / {
# 文件目录地址
show ../../../Users/lxbin/Documents/WWW/
# 是否可以新建
allow_new true
# 是否可以修改
allow_edit true
}
##########################
# 异常处理 #
##########################
errors {
log ../log/error.log
404 404.html # Not Found
500 500.html # Internal Server Error
}
-------------------------------------

Caddy,一个用Go实现的Web Server

这是一个Web Server的时代,apache2nginx共舞,在追求极致性能的路上,没有最高,只有更高。但这又是一个追求个性化的时代,有些Web Server并没有去挤“Performance提升”这一独木桥,而是有着自己的定位,Caddy就是这样一个开源Web Server。
Caddy的作者Matt Holt在caddy官网以及FAQ中对caddy的目标阐释如下: 其他Web Server为Web而设计,Caddy为human设计。功能定位上,与经常充当最前端反向代理的nginx不同,caddy致力于成为一个易用的静态 文件Web Server。可以看出Caddy主打易用性,使用配置简单。并且得益于Go的跨平台特性,caddy很容易的支持了三大主流平台:Windows、 Linux、Mac。在Caddy开发者文档中,我们可以看到caddy还可以在Android(linux arm)上运行。caddy目前版本为0.7.1,还不稳定,且后续版本可能变化较大,甚至与前期版本不兼容,因此作者目前不推荐caddy在生产环境被 重度使用。
关注caddy,是因为caddy填补了go在通用web server这块的空白(也许有其他,但我还不知道),同时Web server in go也“响应”了近期Golang去C化的趋势(Go 1.5中C is gone!),即便caddy作者提到caddy的目标并非如nginx那样。但未来谁知道呢?一旦Go性能足够高时,一旦caddy足够稳定时,自然而 然的就会有人将其用在某些应用的生产环境中替代nginx或apache2了。一套全Go的系统,在部署、运维方面也是有优势的。
一、安装和运行caddy
和诸多go应用一样,我们可以直接从caddy的github.com releases页中找到最新发布版(目前是0.7.1)的二进制包。这里使用的是caddy_darwin_amd64.zip。
下载解压后,进入目录,直接执行./caddy即可将caddy运行起来。
$caddy 0.0.0.0:2015
在浏览器里访问localhost:2015,页面上没有预期显示的类似"caddy works!”之类的默认Welcome页面,而是“404 Not Found"。虽然这说明caddy已经work了,但没有一个default welcome page毕竟对于caddy beginer来说并不友好。这里已经向作者提了一个sugguestion issue
二、caddy原理
Go的net/http标准库已经提供了http server的实现,大多数场合这个http server都能满足你的需要,无论是功能还是性能。Caddy实质上也是一个Go web app,它也import net/http,嵌入*http.Server,并通过handler的ServeHTTP方法为每个请求提供服务。caddy使用 http.FileServer作为处理 静态文件的基础。caddy的诱人之处在于其middleware,将诸多middleware串成一个middleware chain以提供了灵活的web服务。另外caddy中的middleware还可以独立于caddy之外使用。
caddy从当前目录的Caddyfile(默认)文件中读取配置,当然你也可以通过-conf指定配置文件路径。Caddyfile的配置格式 的确非常easy,这也符合caddy的目标。
Caddyfile总是以站点的Addr开始的。
单一站点的Caddyfile样例如下:
//Caddyfile localhost:2015 gzip log ./2015.log
Caddy也支持配置多个站点,类似virtualhost的 配置(80端口多路复用):
//Caddyfile foo.com:80 {     log ./foo.log     gzip }
bar.com:80 {     log ./bar.log     gzip }
为了实现风格上的统一,单一站点也最好配置为如下这种格式(代码内部称之为    Server Block):
localhost:2015 {     gzip     log ./2015.log }
这样Caddyfile的配置文件模板样式类似于下面这样:
host1:port {     middleware1     middleware2 {         … …     }     … … }
host2:port {     middleware1     middleware2 {         … …     }     … … } … …
关于middleware,在caddy文档中有较为详细的说明和例子。对于caddy这样一个年轻的开源项目而言,其文档还算是相对较全的,虽 然现在还不能和nginx、 apache比。
caddy中的middleware就是一个实现了middleware.Handler接口的struct,例如gzip这个 middleware:
// middleware.go type Middleware func(Handler) Handler type Handler interface {         ServeHTTP(http.ResponseWriter, *http.Request) (int, error) }
// gzip/gzip.go type Gzip struct {     Next middleware.Handler }
func (g Gzip) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) {     if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {         return g.Next.ServeHTTP(w, r)     }     …. …     gz := gzipResponseWriter{Writer: gzipWriter, ResponseWriter: w}
    // Any response in forward middleware will now be compressed     status, err := g.Next.ServeHTTP(gz, r)     … … }
middleware.Handler的函数原型与http.Handler的不同,不能直接作为http.Server的Handler使用。caddy使用了下面这个idiomatic go pattern:
type appHandler func(http.ResponseWriter, *http.Request) (int, error)
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {     if status, err := fn(w, r); err != nil {         http.Error(w, err.Error(), status)     } } 当然这个pattern有很多变种,但思路大致类似。一个middleware chain大致就是handler1(handler2(handler3))的调用传递。
前面说过caddy是基于http.FileServer的静态文件Web Server,FileServer总会作为middleware chain的最后一环,如果没有配置任何middleware,那你的server就是一个静态文件server。
三、caddy典型应用
【静态文件Server】
caddy的最基础应用实际就是一个静态文件Server,底层由http.FileServer承载,当然caddy封装了http.FileServer,做了一些拦截处理,最后将w, r传递给http.ServeContent去处理文件数据。
第一次执行./caddy,实际上就启动了一个静态文件Server。但这个server不默认支持你navigate directory。如果你知道website root目录(如果没有指定root,则caddy执行的当前路径会作为website的root路径)下的文件名,比如foo.txt,你可以在浏览器 中输入:localhost:2015/foo.txt,caddy会执行正确的服务,浏览器也会显示foo.txt的全文。
对于静态文件Server,caddy支持在website的root路径下首先查找是否有如下四个文件:
//caddy/middleware/browse/browse.go var IndexPages = []string{     "index.html",     "index.htm",     "default.html",     "default.htm", }
如果查到有其中一个,则优先返回这个文件内容,这就是静态站点的首页。
如果要支持目录文件列表浏览,则需要为website配置browse middleware,这样对于无index file的目录,我们可以看到目录文件列表。
localhost:2015 {     browse }   
【反向代理】
caddy支持基本的反向代理功能。反向代理配置通过proxy middleware实现。
localhost:2015 {     log ./2015.log
    proxy /foo localhost:9001     proxy /bar localhost:9002 }
当你访问localhost:2015/foo时,实际上访问的是9001端口的服务程序; 当你访问localhost:2015/bar时,实际上访问的是9002端口的服务程序。
【负载均衡】
Caddy支持负载均衡配置,并支持三种负载均衡算法:random(随机)、least_conn(最少连接)以及round_robin(轮询调度)。
负载均衡同样是通过proxy middleware实现的。
localhost:2015 {     log ./2015.log
    proxy / localhost:9001 localhost:9003 {         policy round_robin     }     proxy /bar localhost:9002 localhost:9004 {         policy least_conn     } }
【支持fastcgi代理】
caddy同样支持fastcgi代理,可以将请求通过fastcgi接口发送给后端的实现fastcgi的server。我们以一个"hello world"的php server为例。
mac os上自带了php-fpm,一个实现了fastcgi的php cgi进程管理器。caddy将请求转发给php-fpm监听的端口,后者会启动php-cgi解释器,解释index.php,并将结果返回给caddy。
mac os上的php-fpm默认没有随机启动。我们需要简单配置一下:
$mkdir phptest $mkdir -p phptest/etc $mkdir -p phptest/log $cd phptest $sudo cp /private/etc/php-fpm.conf.default ./etc $cd ./etc $sudo chown tony php-fpm.conf.default $mv php-fpm.conf.default php-fpm.conf
编辑php-fpm.conf,保证下面两项是非注释状态的:
error_log = log/php-fpm.log listen = 127.0.0.1:9000 
我们通过network socket进行fastcgi通信。
回到phptest目录下,执行:
php-fpm -p ~/test/go/caddy/phptest
执行后,php-fpm就会转入后台执行了。
接下来我们来配置Caddyfile:
localhost:2015 {     fastcgi / 127.0.0.1:9000 php     log ./2015.log }
这里配置的含义是:将全部请求转发到9000端口,这里的php是一个preset(预配置集合),相当于:
ext   .php split .php index index.php
我们在phptest目录下创建一个index.php文件,内容如下:
<?php echo "Hello World\n"; ?>
好了,现在启动caddy,并使用浏览器访问localhost:2015试试。你会看到"Hello World"呈现在浏览器中。
【git push发布】
对于一些静态站点,caddy支持git directive,实现在server启动以及运行时定期git pull你的项目库,将最新更新pull到server上。
caddy文档中给出两个例子:
第一个是一个php站点,定期pull项目库,实现server更新:
git git@github.com:user/myphpsite {     key /home/user/.ssh/id_rsa } fastcgi / 127.0.0.1:9000 php
第二个是一个hugo支撑的静态站点,每次pull后,执行hugo命令生成新的静态页面:
git github.com/user/site {     path  ../     then  hugo –destination=/home/user/hugosite/public }
注意:git directive并非middleware,而是一个单独的goroutine实现的。
四、小结
caddy的功能不局限于上面的几个例子,上面只是几个最为常见的场景而已。caddy目前还很年轻,应用不多,但知名golang网站 gopheracademy.com(GopherCon组织方)是由Caddy support的。caddy还在积极进化,有兴趣的Gopher可持续关注.
------------------------------------

清新脱俗的Web服务器-Caddy

清新脱俗的 Web 服务器 Caddy 从属于笔者的服务端应用程序开发与系统架构**,我司之前一直使用 Nginx,不过其配置包括一些特性支持相较于 Caddy 略显复杂,可以参考笔者的Nginx 基本配置备忘
清新脱俗的 Web 服务器 Caddy 作为新兴 Web 服务器,Caddy 提供了很多简单易用的功能而没有历史的包袱,其默认支持并且能帮你自动配置 HTTP/2、HTTPS,对于 IPV6、WebSockets 都有很好的支持。基于 Go 编写的 Caddy 天生对于多核具有很好的支持,并且其丰富的插件系统提供了文件管理、文件上传、基于 MarkDown 的博客系统等等开箱即用的扩展功能。我们可以在官方下载界面**选择你需要的插件功能定制个性化二进制文件,下载完毕之后即可以使用caddy命令直接运行。其默认监听 2015 端口,在浏览器中打开 http://localhost:2015** 即可以查看其运行情况。我们也可以通过-conf参数指定配置文件:
$ caddy -conf="/path/to/Caddyfile"
下文我们会详细介绍 Caddyfile 的配置语法,Caddy 的一大特性在于其使用所谓指令(Directives)来描述功能进行配置,相较于 Nginx 或者 Apache 其配置会简化很多。如果我们希望支持多配置文件,可以使用import指令:
import config/common.conf
或者引入整个文件夹:
import ../vhosts/*
Reference 新兴的web服务器caddy
站点配置 典型的 Caddyfile 配置文件如下所示:
localhost
gzip
browse
websocket /echo cat
ext .html
log /var/log/access.log
proxy /api 127.0.0.1:7005
header /api Access-Control-Allow-Origin *
每个 Caddyfile 的第一行必须描述其服务的地址: localhost:2020
之后的每一行都是官方提供的指令,譬如我们需要为服务器添加 gzip 压缩支持,只需要直接添加一个指令:
localhost:2020gzip
我们可以使用bind指令来指定当前服务器绑定的地址:
bind hostbind 127.0.0.1
虚拟主机 如果我们需要配置独立的虚拟主机,需要将配置信息移动到站点名之后的大括号内:
mysite.com { 
root /www/mysite.com
}
sub.mysite.com
 {
 root /www/sub.mysite.com gzip log ../access.log
}
注意,左括号必须与站点名位于同一行,而右括号则是必须单起一行。对于共享相同配置的站点,我们可以用逗号来声明多个站点:
localhost:2020, https://site.com, http://mysite.com 
{
}
当 Caddy 检测到站点名符合下列条件时会自动使用 Let's Encrypt 脚本来为站点添加 HTTPS 支持,并且自动监听 80 与 443 端口: 主机名不可为空并且没有 localhost 与 IP 地址
端口号未明确指定为 80
Scheme 未明确指定为 http
TLS 未被关闭
未指明证书
缓存设置 我们可以通过 expires 指令来设置相较于请求时间的过期头,其基本语法为:
expires { match regex duration}
regex 是用于匹配请求文件的正则表达式,而 duration 则是 0y0m0d0h0i0s 格式的描述时长的表达式,常用的匹配语法为:
expires {
    match some/path/.*.css$ 1y # expires
    css files in some/path after one year
    match .js$ 1m # expires
    js files after 30 days
    match .png$ 1d # expires
    png files after one day
    match .jpg$ 1h # expires
    jpg files after one hour
    match .pdf$ 1i # expires
    pdf file after one minute
    match .txt$ 1s # expires
    txt files after one second
    match .html$ 5i30s # expires
    html files after 5 minutes 30 seconds
}
反向代理 proxy 指令提供了基本的反向代理功能,其支持 Health Checks 以及 Failovers,并且支持对于 WebSocket 的反向代理。其基本语法为:
proxy from to
from 即是请求匹配的基本路径,to 则是请求转发到的端点地址。我们也可以使用更复杂的配置:
proxy from to... {
    policy random | least_conn | round_robin | ip_hash
    fail_timeout duration
    max_fails integer
    try_duration duration
    try_interval duration
    health_check path
    health_check_interval interval_duration
    health_check_timeout timeout_duration
    header_upstream name value
    header_downstream name value
    keepalive number
    without prefix
    except ignored_paths...
    upstream to
    insecure_skip_verify
    preset
}
将所有发往 /api 的请求转发到后端系统:
proxy /api localhost:9005
使用随机策略将所有请求负载均衡到三个后端服务器:
proxy / web1.local:80 web2.local:90 web3.local:100
使用循环机制:
proxy / web1.local:80 web2.local:90 web3.local:100 {
 policy round_robin
}
添加健康检查并且透明转发主机名、地址与上游:
proxy / web1.local:80 web2.local:90 web3.local:100 {
 policy round_robin
 health_check /health transparent
}
转发 WebSocket 请求:
proxy /stream localhost:8080 { websocket}
避免对于部分静态请求的转发:
proxy / backend:1234 { except /static /robots.txt}
WebSocket Caddy 内建支持 WebSocket 连接,其允许客户端发起 WebSocket 连接的时候客户端执行某个简单的指令,其基本语法如下: websocket [path] command
我们可以在客户端内构建简单的 WebSocket 客户端请求:
if (window.WebSocket != undefined) {
  var connection = new WebSocket("ws://localhost:2015/echo");
  connection.onmessage = wsMessage;

  connection.onopen = wsOpen;

  function wsOpen(event) {
    connection.send("Hello World");
  }
  function wsMessage(event) {
    console.log(event.data);
  }
}
function wsMessage(event) {
  console.log(event.data);
}
然后在服务端接收该请求并且将客户端输入的内容返回:
var readline = require('readline');
var rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

rl.on('line', function(line){
    console.log(line);
})
最后 Caddy 文件配置如下:
websocket /echo "node tmp.js"
文件上传 我们可以使用 Caddy 提供的扩展指令 upload 来搭建简单的文件上传服务器:
upload path {
    to                  "directory"
    yes_without_tls
    filenames_form      none|NFC|NFD
    filenames_in        u0000–uff00 [u0000–uff00| …]
    hmac_keys_in        keyID_0=base64(binary) [keyID_n=base64(binary) | …]
    timestamp_tolerance 0..32
    silent_auth_errors
}
直接添加如下配置:
upload /web/path { to "/var/tmp"}
然后使用 curl 上传文件:
upload /web/path {
    to "/var/tmp"
}
或者同时上传多个文件:
# HTTP POST
curl \
  -F gitconfig=@.gitconfig \
  -F id_ed25519.pub=@.ssh/id_ed25519.pub \
  https://127.0.0.1/web/path/
我们也可以使用指令来移动或者删除这些文件:
# MOVE is 'mv'
curl -X MOVE \
  -H "Destination: /web/path/to-release" \
  https://127.0.0.1/web/path/from-release

# DELETE is 'rm -r'
curl -X DELETE \
  https://127.0.0.1/web/path/to-release
访问控制 权限认证 Basic Auth Caddy 内建支持 HTTP Basic Authentication,能够强制用户使用指定的用户名与密码访问某些目录或者文件。其基本配置语法如下:
basicauth username password { resources}
如果我们希望为 /secret 目录下所有文件添加权限认证:
basicauth /secret Bob hiccup
也可以指明某些文件:
basicauth username password {
    resources
}

JWT
jwt 指令是 Caddy 的扩展功能,我们需要在官网上选择添加该功能并且获取编译后的版本,其基本语法为:
```bash
jwt path
// 或者
jwt {
    path  resource
    allow claim value
    deny  claim value
}
譬如我们预设了两个令牌:user: someone 与 role: member ,我们的配置项如下:
jwt {
    path  /protected
    deny  role member
    allow user someone
}
该中间件会拒绝所有 role: member 的访问,除了用户名为 someone 的用户。而另一个 role: admin 或者 role: foo 的用户则可以正常访问。我们可以通过三种方式来提交令牌:
MethodFormatAuthorization HeaderAuthorization: Bearer *token*Cookie"jwt_token": *token*URL Query Parameter/protected?token=*token*跨域请求
我们可以使用 cors 指令来为服务器添加跨域请求的能力:
```bash
cors / {
    origin            http://allowedSite.com
    origin            http://anotherSite.org https://anotherSite.org
    methods           POST,PUT
    allow_credentials false
    max_age           3600
    allowed_headers   X-Custom-Header,X-Foobar
    exposed_headers   X-Something-Special,SomethingElse
}
我们也可以添加 JSONP 的支持:
jsonp /api/status
譬如某个端点返回类似于{"status":"ok"}这样的 JSON 响应,请求格式如下:
$ wget 'http://example.com/api/status?callback=func3022933'
其会返回如下格式的响应:
func3022933({"status":"ok"});
地址过滤 我们可以使用 ipfilter 指令来基于用户的 IP 来允许或者限制用户访问,其基本语法为:
ipfilter paths... {
    rule       block | allow
    ip         list or/and range of IPs...
    country    countries ISO codes...
    database   db_path
    blockpage  block_page
    strict
}
仅允许某个 IP 访问:
```bash
ipfilter / {
    rule allow
    ip   93.168.247.245
}
禁止两段 IP 地址与某个具体的 IP 访问,并且向他们返回默认界面:
ipfilter / {
    rule       block
    ip         192.168.0.0/16 2E80::20:F8FF:FE31:77CF/16 5.23.4.24
    blockpage  /local/data/default.html
}
仅允许来自法国的视野固定 IP 地址的客户端访问:
ipfilter / {
    rule      allow
    country   FR
    database  /local/data/GeoLite2-Country.mmdb
    ip        99.23.4.24 2E80::20::FEF1:91C4
}
仅支持来自美国与日本的客户端访问: ipfilter / { rule allow country US JP database /local/data/GeoLite2-Country.mmdb}
禁止来自美国与日本的客户端对于 /notglobal 与 /secret 的访问,直接返回默认地址:
ipfilter / {
    rule      allow
    country   US JP
    database  /local/data/GeoLite2-Country.mmdb
}
请求限流 我们可以使用 ratelimit 这个扩展指令来为资源添加请求限流的功能,对于单资源可以使用如下指令:
ratelimit path rate burst unit
// 限制客户端每秒最多对于 /r 资源发起两个请求,突发上限最多为 3 个
ratelimit /r 2 3 second
ratelimit path rate burst unit// 限制客户端每秒最多对于 /r 资源发起两个请求,突发上限最多为 3 个ratelimit /r 2 3 second
对于多资源可以使用如下指令:
ratelimit rate burst unit {
    resources
}
// 限制对于资源文件的访问时长为 2 分钟
ratelimit 2 2 minute {
    /foo.html
    /dir
}
链接:http://www.jianshu.com/p/34936193c9e1

No comments:

Post a Comment