分类目录归档:服务器

acme.sh 用法

安装 acme.sh

curl https://get.acme.sh | sh -s email=jishudiandi@outlook.com

设置别名,方便使用:

alias acme.sh=~/.acme.sh/acme.sh

申请证书:

acme.sh --issue -d tool.jsdd.net  --nginx

acme.sh --issue -d tool.jsdd.net  --webroot /var/www/ohss.top 

部署证书:

acme.sh --install-cert -d tool.jsdd.net --key-file /etc/nginx/ssl/tool.jsdd.net.key --fullchain-file /etc/nginx/ssl/tool.jsdd.net.pem --reloadcmd "service nginx force-reload"

删除证书:

acme.sh --remove -d tool.jsdd.net

删除后记得到 /root/.acme.sh/ 目录下找到域名文件夹,一并删除。

官方文档:https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

关于FreshRSS的一些记录

Freshrss推荐的API是 Google Reader API

移动客户端可以用 Fluent Reader Lite

FreshRSS自动更新订阅,需要用到系统定时任务。

使用以下命令编辑 www-data 用户的 crontab:

sudo crontab -u www-data -e

在打开的 crontab 编辑器中,添加以下行:

10 * * * * php -f /var/www/freshrss.wujie.me/app/actualize_script.php > /tmp/FreshRSS.log 2>&1

保存并退出编辑器,这样,定时任务就会每小时的第 10 分钟运行,并将输出记录到 /tmp/FreshRSS.log 文件中。

ACME.sh自动证书管理

https://github.com/acmesh-official/acme.sh/wiki/%E8%AF%B4%E6%98%8E

按文档做就行。

acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.

主要步骤:

  1. 安装 acme.sh
  2. 生成证书
  3. copy 证书到 nginx/apache 或者其他服务
  4. 更新证书
  5. 更新 acme.sh
  6. 出错怎么办, 如何调试

下面详细介绍.

1. 安装 acme.sh

安装很简单, 一个命令:

curl https://get.acme.sh | sh -s email=my@example.com

普通用户和 root 用户都可以安装使用. 安装过程进行了以下几步:

  1. 把 acme.sh 安装到你的 home 目录下:

~/.acme.sh/

并创建 一个 shell 的 alias, 例如 .bashrc,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh

  1. 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

更高级的安装选项请参考:  https://github.com/Neilpang/acme.sh/wiki/How-to-install

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/

2. 生成证书

acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: http 和 dns 验证.

1. http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.

acme.sh –issue -d mydomain.com -d www.mydomain.com –webroot /home/wwwroot/mydomain.com/

只需要指定域名, 并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用.

如果你用的 apache服务器, acme.sh 还可以智能的从 apache的配置中自动完成验证, 你不需要指定网站根目录:

acme.sh –issue -d mydomain.com –apache

如果你用的 nginx服务器, 或者反代, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:

acme.sh –issue -d mydomain.com –nginx

注意, 无论是 apache 还是 nginx 模式, acme.sh在完成验证之后, 会恢复到之前的状态, 都不会私自更改你本身的配置. 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置, 否则只能成功生成证书, 你的网站还是无法访问https. 但是为了安全, 你还是自己手动改配置吧.

如果你还没有运行任何 web 服务, 80 端口是空闲的, 那么 acme.sh 还能假装自己是一个webserver, 临时听在80 端口, 完成验证:

acme.sh –issue -d mydomain.com –standalone

更高级的用法请参考:  https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert

2. 手动 dns 方式, 手动在域名上添加一条 txt 解析记录, 验证域名所有权.

这种方式的好处是, 你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证. 坏处是,如果不同时配置 Automatic DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。

acme.sh –issue –dns -d mydomain.com \
 –yes-I-know-dns-manual-mode-enough-go-ahead-please

然后, acme.sh 会生成相应的解析记录显示出来, 你只需要在你的域名管理面板中添加这条 txt 记录即可.

等待解析完成之后, 重新生成证书:

acme.sh –renew -d mydomain.com \
  –yes-I-know-dns-manual-mode-enough-go-ahead-please

注意第二次这里用的是 –renew

dns 方式的真正强大之处在于可以使用域名解析商提供的 api 自动添加 txt 记录完成验证.

acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等数十种解析商的自动集成.

以 dnspod 为例, 你需要先登录到 dnspod 账号, 生成你的 api id 和 api key, 都是免费的. 然后:

export DP_Id=”1234″

export DP_Key=”sADDsdasdgdsf”

acme.sh –issue –dns dns_dp -d aa.com -d www.aa.com

证书就会自动生成了. 这里给出的 api id 和 api key 会被自动记录下来, 将来你在使用 dnspod api 的时候, 就不需要再次指定了. 直接生成就好了:

acme.sh –issue -d mydomain2.com –dns  dns_dp

更详细的 api 用法:  https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md

3. copy/安装 证书

前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.

注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.

正确的使用方法是使用 –install-cert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:

Apache example:

acme.sh –install-cert -d example.com \
–cert-file      /path/to/certfile/in/apache/cert.pem  \
–key-file       /path/to/keyfile/in/apache/key.pem  \
–fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
–reloadcmd     “service apache2 force-reload”

Nginx example:

acme.sh –install-cert -d example.com \
–key-file       /path/to/keyfile/in/nginx/key.pem  \
–fullchain-file /path/to/fullchain/nginx/cert.pem \
–reloadcmd     “service nginx force-reload”

(一个小提醒, 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload)

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

–install-cert命令可以携带很多参数, 来指定目标文件. 并且可以指定 reloadcmd, 当证书更新以后, reloadcmd会被自动调用,让服务器生效.

详细参数请参考:  https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc

值得注意的是, 这里指定的所有参数都会被自动记录下来, 并在将来证书自动更新以后, 被再次自动调用.

4. 查看已安装证书信息

acme.sh –info -d example.com
# 会输出如下内容:
DOMAIN_CONF=/root/.acme.sh/example.com/example.com.conf
Le_Domain=example.com
Le_Alt=no
Le_Webroot=dns_ali
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_Keylength=
Le_OrderFinalize=https://acme-v02.api.letsencrypt.org/acme/finalize/23xxxx150/781xxxx4310
Le_LinkOrder=https://acme-v02.api.letsencrypt.org/acme/order/233xxx150/781xxxx4310
Le_LinkCert=https://acme-v02.api.letsencrypt.org/acme/cert/04cbd28xxxxxx349ecaea8d07
Le_CertCreateTime=1649358725
Le_CertCreateTimeStr=Thu Apr  7 19:12:05 UTC 2022
Le_NextRenewTimeStr=Mon Jun  6 19:12:05 UTC 2022
Le_NextRenewTime=1654456325
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/etc/acme/example.com/privkey.pem
Le_ReloadCmd=service nginx force-reload
Le_RealFullChainPath=/etc/acme/example.com/chain.pem

5. 更新证书

目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.

请确保 cronjob 正确安装, 看起来是类似这样的:

crontab  -l

56 * * * * “/root/.acme.sh”/acme.sh –cron –home “/root/.acme.sh” > /dev/null

6. 关于修改ReloadCmd

目前修改ReloadCmd没有专门的命令,可以通过重新安装证书来实现修改reloadCmd的目的。 此外,安装证书后,相关信息是保存在~/.acme.sh/example.com/example.conf文件下的,内容就是acme.sh –info -d example.com输出的信息,不过ReloadCmd在文件中使用了Base64编码。理论上可以通过直接修改该文件来修改ReloadCmd,且修改时,无需Base64编码,直接写命令原文acme.sh也可以识别。 不过,example.conf文件的位置和内容格式以后可能会改变!example.conf一直都是内部使用, 后面有可能会改为用 sqlite 或者mysql 格式存储. 所以一般不建议自己修改。

7. 更新 acme.sh

目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步.

升级 acme.sh 到最新版 :

acme.sh –upgrade

如果你不想手动升级, 可以开启自动升级:

acme.sh –upgrade –auto-upgrade

之后, acme.sh 就会自动保持更新了.

你也可以随时关闭自动更新:

acme.sh –upgrade –auto-upgrade  0

8. 出错怎么办:

如果出错, 请添加 debug log:

acme.sh –issue  …..  –debug

或者:

acme.sh –issue  …..  –debug  2

请参考:  https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh

在DNS验证模式下如果debug中出现诸如”timed out”等字样可能是因为GFW拦截了相应请求,需要添加http(s) proxy环境变量。(请按照自己实际设定修改)

export http_proxy=”socks5h://localhost:1081″ && export https_proxy=”socks5h://localhost:1081″

如果是使用docker则完整示例配置如下:

docker run –rm  -it  \
  -v “/etc/acme”:/acme.sh  \
  -e “CF_Token=[填入自己的信息]” \
  -e “CF_Account_ID=[填入自己的信息]” \
  -e “CF_Zone_ID=[填入自己的信息]” \
  -e http_proxy=”socks5h://[代理A]:1234″ \
  -e https_proxy=”socks5h://[代理A]:1234″ \
  –network container:[代理A]\
  neilpang/acme.sh \
  –issue -d example.com –dns dns_cf –debug

上述例子中使用cloudflare的DNS来签发证书,并通过把acme.sh链接到容器[代理A],来转发curl请求(请按照自己实际设定修改)

最后, 本文并非完全的使用说明, 还有很多高级的功能, 更高级的用法请参看其他 wiki 页面.

https://github.com/Neilpang/acme.sh/wiki

Apache在Windows上作为服务运行

安装服务: httpd -k install  

被安装的服务名称是Apache2.2,使用的配置文件是conf\httpd.conf

httpd -k install -n  “service name”  #如果想指定服务名称,请采用该命令

httpd -k start #启动apache服务

httpd -k stop 或 httpd -k shutdown #停止apache服务

httpd -k restart #重启apahce服务

启动前,你可以通过httpd -n “service name” -t 检查配置文件的正确性

如果采用默认的服务名,那么默认的命令就是: httpd -t

删除服务:

httpd -k uninstall #删除默认的服务名

httpd -k uninstall -n “service name” #删除指定的文件名

使用squid搭建HTTP代理服务器

yum install squid

/etc/squid/squid.conf 是squid的配置文件

/var/log/squid/access.log 是访问日志

打开/etc/squid/squid.conf 文件并配置内容如下

http_port 3128 是代理端口,可以改为需要的端口

修改后重启服务即可实现代理上网了

service squid restart

如果需要用户名以及密码验证,需要先创建用户,步骤如下:

yum install httpd-tools -y   (用于安装htpasswd工具)
htpasswd  -c /etc/squid/squid_user.txt  (用于创建用户名和密码)

然后把下面的代码加到如图的位置

auth_param basic program /usr/lib64/squid/basic_ncsa_auth  /etc/squid/squid_user.txt
acl auth_user proxy_auth REQUIRED
http_access allow auth_user

注释掉以前的http_access的配置,改为红框里的代码即可。

Supervisor部署ASP.NET core配置文件

在部署asp.net core的应用程序时,为防止进程退出,可以使用supervisor来守护asp.net core应用的进程,对于一个asp.net core应用supervisor配置如下,可以作为模板修改使用。

[program:pcsweb]
directory=/www/pcsweb
command=dotnet /www/pcsweb/YiSha.Admin.Web.dll
autostart=true
autorestart=true
stdout_logfile=/var/log/pcsweb_stdout.log
stderr_logfile=/var/log/pcsweb_stderr.log
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

Supervisor常用命令

supervisor常用命令,记录备忘。

supervisorctl   status              查看状态
supervisorctl   reload              重新载入配置文件
supervisorctl   start all/ftp     启动所有/指定的程序进程
supervisorctl   stop all/frp      关闭所有/指定的程序进程 

supervisorctl   restart pcsweb  重启进程

重启supervisor
systemctl restart supervisord

Supervisor 部署Django网站的配置

和asp.net core应用类似,django也是需要守护进程来守护的,配置如下:

[program:django-python]
#项目目录
direct=/var/www/www.example.com
#启动进程命令
command=/bin/bash -c "python3 /var/www/www.example.com/manage.py runserver 127.0.0.1:8080"
#是否自动启动
autostart=true
#是否自动重启
autorestart=true
stdout_logfile=/var/log/django_stdout.log
stderr_logfile=/var/log/django_stderr.log
user=root
stopsignal=TERM
startsecs=5
startretries=3
stopasgroup=true
killasgroup=true

解决 Nginx SSL 证书报错

闲来无事,查看了一下 nginx 的 error.log 日志文件,发现里面大量的报错信息:

cannot load certificate "data:": PEM_read_bio_X509_AUX() failed (SSL: error:0909006C:PEM routines:get_name:no start line:Expecting: TRUSTED CERTIFICATE) while SSL handshaking…

是 ssl 证书报错了,想了一下,整个服务器只有这个博客使用了 https ,理所当然的从博客的 nginx 配置文件和证书文件入手,历时三天也没找到原因,甚至一度把证书都更换了,从腾讯云的 SSL 证书换到了阿里云的 SSL 证书,结果还是报错,说明证书没问题。

就在快要放弃的时候,突然想到,之前为了屏蔽直接从 ip 来的请求,加了一些配置,屏蔽了http://iphttps://ip两种访问形式,而屏蔽 https+ip 也涉及到了 SSL 证书的问题,当时是通过 map 映射给了一个空证书,会不会是这个原因?

于是,为了验证这个猜想,把博客站点的错误日志和其它站点的分开,单独统计。过了一夜,第二天打开日志文件查看,果然,博客的错误日志中并没有此错误,只有 error.log 里面有,这就说明错误不是博客站点的 SSL 证书引起的,那么只可能是之前屏蔽 https+ip 的配置引起的。

找到了原因,那么解决起来就快了。

先帖一下之前的配置:

map "" $empty {
    default "";
}
server {
    listen 80 default_server;
    listen 443 ssl http2 default_server;
    listen [::]:80 default_server;
    listen [::]:443 ssl http2 default_server;
    server_name _;

    ssl_ciphers aNULL;
    ssl_certificate data:$empty;
    ssl_certificate_key data:$empty;
    return 444;
}

把上面的配置改成如下:

# 禁止直接通过IP访问网站
server {
    listen 80 default_server;
    server_name _;
    return 444;
}

删除了屏蔽 https+ip 的配置,只保留屏蔽 http+ip 的配置。然后在博客站点的 nginx 配置文件中添加如下代码:

# 通过 default_server 把博客站点设置为默认的 https 站点
listen 443 ssl http2 default_server;

if ($host != 'wujie.me') {
    rewrite ^/(.*)$ https://wujie.me/$1 permanent;
    break;
}

把直接从非域名来的请求(包括从 ip 来的请求)跳转到域名就可以了。

这样修改后,经过两天的观察,没有再出现错误,问题解决!