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访问网页,提示证书无效,则需要将该网址加入浏览器白名单。