移植ARM-Linux Lighttpd-1.4.75,实现支持https+cgi的web服务器

avatar
作者
猴君
阅读量:1

1. 声明:

该篇文章是在 arm 移植 lighttpd + CGI 配置 的基础上,根据实际移植过程中遇到的一些问题添加了一些补充,同时还借鉴了:
lighttpd双向认证-openssl证书生成及配置
Lighttpd 配置 SSL
lighttpd 配置文件的路径

2. 环境介绍:

需要一个arm平台的方案。

编译lighttpd需要依赖pcre,所以先编译好pcre,也需要引用openssl的库,编译openssl可见另一篇博客:
更新移植ARM-Linux openSSH 版本到openssh-9.7p1

version:

  • lighttpd:1.4.75
  • pcre:8.45
  • openssl: 3.2.0

交叉编译链版本:
gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux

3. 编译


一个脚本解决所有问题:

## #    Copyright By Schips, All Rights Reserved #    https://gitee.com/schips/ # #    File Name:  make.sh #    Created  :  2020-07-31 09:38:39 # ## #!/bin/sh  BASE=`pwd` BUILD_HOST=/home/cc/CC/arm-linux-gcc/IOT-NET-S/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/arm-linux-gnueabihf- # 最终的运行环境 INSTALL=${BASE}/install FIN_INSTALL=${BASE}/lighttpd LIGHTTPD_INSTALL=/root/lighttpd_install  LIGHTTPD=lighttpd-1.4.75 PCRE=pcre-8.45  make_dirs() {     cd ${BASE}     mkdir  compressed  install lighttpd lighttpd/${LIGHTTPD} lighttpd/${PCRE} source -p }  tget () { #try wget     filename=`basename $1`     echo "Downloading [${filename}]..."     if [ ! -f ${filename} ];then         wget $1     fi      echo "[OK] Downloaded [${filename}] " }  download_package () { 	echo "***************************************************************************************************" 	echo "download_package..."     cd ${BASE}/compressed     #下载包     tget https://download.lighttpd.net/lighttpd/releases-1.4.x/${LIGHTTPD}.tar.gz 	tget https://jaist.dl.sourceforge.net/project/pcre/pcre/8.45/${PCRE}.tar.gz }  tar_package () { 	echo "***************************************************************************************************" 	echo "tar_package..."     cd ${BASE}/compressed     ls * > /tmp/list.txt     for TAR in `cat /tmp/list.txt`     do         tar -xf $TAR -C  ../source     done     rm -rf /tmp/list.txt }  set_compile_env () { 	echo "***************************************************************************************************" 	echo "set_compile_env..."     #GCC_PATH=`whereis gcc | awk -F: '{print $2}' | awk '{print $1}' | xargs dirname`     #export PATH=$PATH:$GCC_PATH 	export CC=${BUILD_HOST}gcc 	export CXX=${BUILD_HOST}g++ 	export AR=${BUILD_HOST}ar 	export LD=${BUILD_HOST}ld 	export RANLIB=${BUILD_HOST}ranlib 	export STRIP=${BUILD_HOST}strip }  make_lighttpd () { 	echo "***************************************************************************************************" 	echo "make_lighttpd..."     cd ${BASE}/source/${LIGHTTPD} 	#./configure --prefix=${FIN_INSTALL} --host=arm-linux-gnueabihf  --build=i686-pc-linux --disable-FEUTARE --disable-ipv6 --disable-lfs  --without-bzip2 \ 	#	  && echo "${FIN_INSTALL} with ${BUILD_HOST}gcc" > ${BASE}/ccinfo 	 	./configure \ 		--prefix=${LIGHTTPD_INSTALL} \ 		--host=arm-linux-gnueabihf \ 		--disable-FEUTARE \ 		--disable-ipv6 \ 		--disable-lfs  \ 		--without-zlib	\ 		--without-bzip2 \ 		--with-pcre \ 		PCRECONFIG=${FIN_INSTALL}/${PCRE}/bin/pcre-config \ 		PCRE_LIB=${FIN_INSTALL}/${PCRE}/lib/libpcre.a \ 		CFLAGS="-I${FIN_INSTALL}/${PCRE}/include $CFLAGS" \ 		--with-openssl \ 		--with-openssl-includes=/home/cc/CC/test/openssh/test/install/openssl-3.2.0/include/ \ 		--with-openssl-libs=/home/cc/CC/test/openssh/test/install/openssl-3.2.0/lib \ 		&& echo "${FIN_INSTALL} with ${BUILD_HOST}gcc" > ${BASE}/ccinfo      make  }  make_pcre () { 	echo "***************************************************************************************************" 	echo "make_pcre..."     cd ${BASE}/source/${PCRE} 	#./configure --prefix=${FIN_INSTALL} --host=arm-linux-gnueabihf  --build=i686-pc-linux --disable-FEUTARE --disable-ipv6 --disable-lfs  --without-bzip2 \ 	#	  && echo "${FIN_INSTALL} with ${BUILD_HOST}gcc" > ${BASE}/ccinfo 	 	./configure --host=arm-linux-gnueabihf --prefix=${FIN_INSTALL}/${PCRE} --enable-utf8 --enable-unicode-properties      make  	make install }  make_lighttpd_install () { 	echo "***************************************************************************************************" 	echo "make_lighttpd_install..."     mkdir ${BASE}/install/lib  -p     mkdir ${BASE}/install/sbin -p     cd ${BASE}/source/${LIGHTTPD}     SRCTOP=`pwd`     echo "${FIN_INSTALL} with ${BUILD_HOST}gcc" > ${BASE}/ccinfo     cp ${BASE}/ccinfo               ${BASE}/install     cp $SRCTOP/src/.libs/*.so       ${BASE}/install/lib  -r     cp $SRCTOP/src/lighttpd-angel   ${BASE}/install/sbin     cp $SRCTOP/src/lighttpd         ${BASE}/install/sbin     #cp `find . -type f -name "lighttpd.conf" 2> /dev/null | grep doc` -v ${BASE}/install/sbin     cp $SRCTOP/doc/config  -r       ${BASE}/install/     rm  ${BASE}/install/config/Make* } make_dirs && \ download_package && \ set_compile_env	&& \ tar_package	&& \ make_pcre	&& \ make_lighttpd	&& \ make_lighttpd_install exit $? she 

编译后生成的文件有:
最终生成的文件结构如下:

install ├── ccinfo  : 编译过程中的一点信息,可以删除 ├── config  : 配置文件目录 ├── lib     : lib库 └── sbin    : 可执行程序目录 

4. 拷贝文件到ARM板:

将整个install目录拷贝到ARM板上:我在这里使用U盘拷贝
执行下面命令创建目录,并将对应的文件拷贝进去:

mkdir -p /etc/lighttpd mkdir -p /usr/lib/lighttpd  rm -rf /etc/lighttpd/* rm -rf /usr/lib/lighttpd/* rm -rf /usr/sbin/lighttpd  cp -rf ./install/config/* /etc/lighttpd/ cp -rf ./install/lib/* /usr/lib/lighttpd/ cp -rf ./install/sbin/* /usr/sbin/  # lighttpd运行时会到/usr/lib中查找mod_*.so库,可以通过下面命令创建软链接 cd /usr/lib find /usr/lib/lighttpd/ -type f -name '*.so*' -exec sh -c 'ln -s "{}" "$(basename "{}")"' \;  # 也可以将lighttpd中so库直接拷贝到/usr/lib中  

5. 生成ssl证书:

#CA: openssl genrsa -out ca-key.pem 4096 openssl req -new -key ca-key.pem -out ca-req.csr -subj "/C=CN/ST=SD/L=JN/O=AA/OU=BB/CN=CC-CA" openssl x509 -req -in ca-req.csr -out ca-cert.pem -signkey ca-key.pem -days 3650 # #SERVER: openssl genrsa -out server-key.pem 2048 # CN=IP ip可根据具体实际情况进行修改,这里生成自签名证书用于开发测试,绑定IP也是方便测试,实际使用中需要申请有效的证书,以及绑定域名,绑定IP的话,设备IP变动,则这个证书会不可用。 openssl req -new -out server-req.csr -key server-key.pem -subj "/C=CN/ST=SD/L=JN/O=AA/OU=BB/CN=192.168.5.132" openssl x509 -req -in server-req.csr -out server-cert.pem -signkey server-key.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -days 3650 #为Lighttpd配置的server证书 cat server-key.pem server-cert.pem >server.pem  

将证书拷贝到指定目录中:

cp server.pem /etc/ssl/private/ cp ca-cert.pem /etc/ssl/private/  

6. 配置:

需要配置的文件有

  • lighttpd.conf
  • modules.conf
  • conf.d/cgi.conf

lighttpd.conf:
修改路径:

var.server_root = "/usr/local/boa"  # 工作路径,网站根目录 映射在机器上的物理路径 var.conf_dir    = "/etc/lighttpd"   # lighttpd配置路径 

修改组:

lighttpd.conf文件中:注释掉username行,

#server.username  = "lighttpd" #server.groupname = "lighttpd 

否则会出现:

can't find username lighttpd 

其他:

文件系统不能读写的话用#号注释掉这两个选项:

#server.errorlog   #accesslog.filename 

修改工作路径:
这个工作路径则是网页文件的存放路径,例如:/usr/local/boa/www

server.document-root        = "/usr/local/boa/www" # 或者: server_root 在前面var.server_root设置 server.document-root = server_root + "/www" 

开启ssl支持:

server.modules += ( "mod_openssl" )  

修改 lighttpd 站点配置
下面是 lighttpd.conf 文件中关于 SSL 的部分配置

$SERVER["socket"] == "*:443" {                                                         ssl.engine  = "enable"      	# ssl.pemfile 指定服务器证书                                                    ssl.pemfile = "/etc/ssl/private/server.pem" 	# ssl.ca-file 指定CA根证书 	ssl.ca-file = "/etc/ssl/private/ca-cert.pem"     # server.name 指定域名,与证书中绑定的域名要一致,由于证书绑定的是IP,顾这里不设置     # server.name = "example.com"     # server.document-root 指定改站点的工作路径,专属于该站点,前面设置的是全局的,已设置全局,顾这里不设置     # server.document-root = "/var/www" } 

强制定向到 HTTPS: 可以不设置
下面是 lighttpd.conf 文件中关于强制 HTTP 定向到 HTTPS 的部分配置

$HTTP["scheme"] == "http" {     # capture vhost name with regex conditiona -> %0 in redirect pattern     # must be the most inner block to the redirect rule     $HTTP["host"] =~ ".*" {         url.redirect = (".*" => "https://%0$0")     } } 

CGI支持
CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上,提供同客户端 HTML 页面的接口。

我们这里以自定义的cgi程序处理为例子。

确定目录结构
假定目录位于/home/xx/lighttpd/,目录结构如下:

/home/xx/lighttpd/install install ├── config │   ├── conf.d │   ├── lighttpd.conf │   ├── modules.conf │   └── vhosts.d ├── lib └── sbin 

说明:

由于这个版本的lighttpd是很新的一个版本,很多文章的配置都有一些变化。但是实际上是类似的。

新版lighttpd.conf中,include了很多子配置,例如include “modules.conf”。

如果需要配置cgi,一般在modules.conf中使能include conf.d/cgi.conf比较合理。

当然,也可以在lighttpd.conf中注释掉include “modules.conf”,将所有的配置写在lighttpd.conf里面。

配置modules.conf:

指定要加载的服务器模块

server.modules = ( #  "mod_rewrite",                                              "mod_access",                                                   #  "mod_auth",                                           #  "mod_authn_file",                         #  "mod_redirect",                                                 #  "mod_setenv",                                     "mod_alias",                                ) 
  • mod_rewrite: 允许您根据规则重写URL,这在许多Web应用程序中都是有用的。
  • mod_access: 提供了基于IP地址、用户名或其他条件的访问控制功能。
  • mod_auth 和 mod_authn_file: 这两个模块通常一起使用,提供基于文件的身份验证功能,如使用.htpasswd文件来存储用户名和密码。
  • mod_redirect: 允许您设置HTTP重定向,即将一个URL重定向到另一个URL。
  • mod_setenv: 允许您设置环境变量,这些变量可以在其他模块或请求处理过程中使用。
  • mod_alias: 允许您将URL路径映射到文件系统中的其他位置。

使能include conf.d/cgi.conf

include conf_dir + "/conf.d/cgi.conf" 

配置conf.d/cgi.conf:

# 确保 此行有效: server.modules += ( "mod_cgi" )  # 修改 cgi.assign 	## 注:对于带扩展名且需要特定解析程序执行的CGI,可以指定解析程序的路径  cgi.assign                 = ( ".pl"  => "/usr/bin/perl",                                ".rb"  => "/usr/bin/ruby",                                ".erb" => "/usr/bin/eruby", 	## 对于带扩展名却不需要特定解析程序就能执行的CGI,可指定解析程序为空,此时可由html中指定需要执行的cgi程序。(例如下面这行)                                # 新增这一行                                ".cgi" => "",                                                                ".py"  => "/usr/bin/python" )                                 	## 对于不带扩展名的CGI程序,只能通过固定路径存取了,如: 	##   cgi.assgin = ( "/cgi-bin/mycgi" => "/usr/local/cgi/mycgi ) 

指定URL映射路径:

alias.url += ( "/cgi-bin" => server_root + "/cgi-bin" ) 

7. 执行lighttpd服务:

完成上述的步骤一般就可以运行lighttpd的服务了,实现通过https访问cgi的网页。

使用以下命令指定配置文件进行运行lighttpd服务

lighttpd -f /etc/lighttpd/lighttpd.conf 

执行执行命令可能会遇到下述问题:

2024-05-09 12:31:33: (configfile.c.1777) opening errorlog '/var/log/lighttpd/error.log' failed: No such file or directory 2024-05-09 12:31:33: (server.c.1935) Opening errorlog failed. Going down. daemonized server failed to start; check error log for details 

这是因为没有创建对应的error.log文件,主要是/var/log/lighttpd/ 路径不存在,需要手动创建:

mkdir -p /var/log/lighttpd/ 

需要注意的有三个库

  • mod_openssl.so
    如果在运行lighttpd时保持,提示找不到该库,则可能是在编译时没有链接openssl的库,具体看编译脚本中的–with-openssl选项。引用openssl的库需要事先编译好openssl,编译openssl可以查看另一篇博客:
    更新移植ARM-Linux openSSH 版本到openssh-9.7p1

  • libssl.so.3
    如果在运行lighttpd时保持,提示找不到该库,则可能是ARM板上的openssl版本比较低,而在编译时引用了高版本的openssl,导致需要openssl高版本的libssl.so.3库,就算是ARM板上有/usr/lib/libssl.so,进行创建libssl.so.3的软链接也不行。
    解决办法主要有两种:
    1、将ARM板的openssl版本更新到高版本,但这比较麻烦
    2、将编译时引用的高版本openssl编译出来的libssl.so.3库拷贝到ARM板的/usr/lib/中。

  • libcrypto.so.3

    lighttpd: error while loading shared libraries: libcrypto.so.3: cannot open shared object file: No such file or directory 

    如果在运行lighttpd时保持,提示找不到该库,则可能是ARM板上的openssl版本比较低,而在编译时引用了高版本的openssl,导致需要openssl高版本的libcrypto.so.3库
    解决办法主要有两种:
    1、将编译时引用的高版本openssl编译出来的libcrypto.so.3库拷贝到ARM板的/usr/lib/中。

8. 最后:

要是想让浏览器正常访问该通过lighttpd创建的web服务器,还是需要一个合格有效的CA证书,以及需要一个域名,方便后续可以更改IP也不影响证书的有效性。

如果测试阶段,浏览器也还是不能通过https访问网页,提示证书无效,则需要将该网址加入浏览器白名单。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!