2022年4月

背景

几年前,之前工作的部门为了方便连接到云环境私网网络,搭建了OpenVPN服务端,所有同事连接之后即可拨入私网网络进行直连访问与程序调试。某天,部门负责人联系说所有客户端均无法拨入,查看服务端日志发现如下错误信息:

Thu Apr 14 16:53:41 2022 27.115.3.186:16890 TLS Error: TLS handshake failed
Thu Apr 14 16:53:41 2022 27.115.3.186:16890 SIGUSR1[soft,tls-error] received, client-instance restarting
Thu Apr 14 16:53:41 2022 27.115.3.186:16949 TLS: Initial packet from [AF_INET]27.115.3.186:16949, sid=b5820c7e 6a773959
Thu Apr 14 16:53:41 2022 27.115.3.186:16950 TLS: Initial packet from [AF_INET]27.115.3.186:16950, sid=cfca97f5 18cff2fe
Thu Apr 14 16:53:42 2022 27.115.3.186:16893 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)

原因

查看上下文,发现了报错信息中的关键点:

Thu Apr 14 16:29:58 2022 WARNING: Your certificate has expired!

于是找到OpenVPN服务端配置目录“/etc/openvpn”,使用如下命令进行证书有效期验证:

openssl x509 -noout -text -in server.crt

验证结果如下(隐去部分关键信息):


Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            3e:e4:c1:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:93
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=Easy-RSA CA
        Validity
            Not Before: Apr 30 04:54:55 2019 GMT
            Not After : Apr 14 04:54:55 2022 GMT
        Subject: CN=server
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:b8:36:xx:xx:xx:xx:xx:xx:xx:xx:3a:06:5e:b2:
...

可以看到,“Not After”字段明确指示了该证书的过期时间,为报障当天中午12天54分(GMT时间根据东八区加8小时)。

当时安装OpenVPN服务端时,因为计划是临时使用一段时间,所以证书的有效期仅仅设置了3年,没想到3年过去了,这个拨入途径已经成为了部门内正常开展工作的基础设施……

(P.S. 遇到问题经常是先临时解决问题,后面再想更好的方案。但用着用着,这个临时的方案就成为了常态化方案……)

处理过程

既然证书已过期,那么现在的当务之急就是需要尽快替换新证书,保障其他同事尽早恢复正常工作。

首先新建一个空文件夹,用于存放新证书相关文件。

mkdir /etc/openvpn/cert_new

当时搭建OpenVPN时,使用的是easy-rsa进行证书生成,因此将之前的easy-rsa拷贝至cert_new文件夹,

cp -r /etc/openvpn/easy-rsa /etc/openvpn/cert_new

进入新的easy-rsa文件夹,删除旧的pki文件夹。

rm -rf pki

使用“easyrsa”命令新建pki目录:

[root@xxx easy-rsa]# ./easyrsa init-pki

init-pki complete; you may now create a CA or requests.
Your newly created PKI dir is: /etc/openvpn/cert_new/easy-rsa/pki

生成ca证书:

[root@xxx easy-rsa]# ./easyrsa --batch build-ca nopass

Generating RSA private key, 2048 bit long modulus
...............................................................................................................+++
...................+++
e is 65537 (0x10001)

生成服务端证书(前面的环境变量代表证书超时天数为3650天):

[root@xxx easy-rsa]# EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-server-full server nopass

Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
................+++
......+++
writing new private key to '/etc/openvpn/cert_new/easy-rsa/pki/private/server.key.c8ybv0BPWo'
-----
Using configuration from /etc/openvpn/cert_new/easy-rsa/pki/safessl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'server'
Certificate is to be certified until Apr 26 07:27:46 2032 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

生成客户端证书:

[root@xxx easy-rsa]# EASYRSA_CERT_EXPIRE=3650 ./easyrsa build-client-full client nopass


Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Generating a 2048 bit RSA private key
.........+++
.............+++
writing new private key to '/etc/openvpn/cert_new/easy-rsa/pki/private/client.key.nsEQpRpArw'
-----
Using configuration from /etc/openvpn/cert_new/easy-rsa/pki/safessl-easyrsa.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'client'
Certificate is to be certified until Apr 26 07:30:30 2032 GMT (3650 days)

Write out database with 1 new entries
Data Base Updated

生成crl.pem文件:

[root@xxx easy-rsa]# EASYRSA_CRL_DAYS=3650 ./easyrsa gen-crl

Using SSL: openssl OpenSSL 1.0.2k-fips  26 Jan 2017
Using configuration from /etc/openvpn/cert_new/easy-rsa/pki/safessl-easyrsa.cnf

An updated CRL has been created.
CRL file: /etc/openvpn/cert_new/easy-rsa/pki/crl.pem

将这些文件统一复制到/etc/openvpn/cert_new目录:

cp pki/ca.crt pki/private/ca.key pki/issued/server.crt pki/private/server.key pki/crl.pem /etc/openvpn/cert_new

为避免权限问题,将crl.pem的所有者改为nobody:

chown nobody:nobody crl.pem 

进入/etc/openvpn/cert_new目录,使用openssl命令验证证书有效性:

[root@xxx cert_new]# openssl verify -CAfile ca.crt -purpose sslserver server.crt

server.crt: OK

生成OpenVPN所需的secret文件ta.key:

 openvpn --genkey --secret ta.key

将所有需要的文件复制到/etc/openvpn

cp ca.crt ca.key crl.pem easy-rsa server.crt server.key ta.key /etc/openvpn

重启OpenVPN服务,即可使OpenVPN加载新的证书文件。

通知所有客户端重新拨号,成功拨入,问题解决。

Android Studio(以下简称AS)升级到最新的Bumblebee 211版本之后,插件市场里面是找不到Lombok插件的,如下图:

iShot2022-04-16_23.16.51.png

而且手工安装插件的时候,会出现版本支持过旧的提示,报错信息如下:

Plugin 'Lombok'(version '0.34.1-2019.1')is not compatible with the current version of the IDE, because it requires build 191.* or older but the current build is AI-211.7628.21

报错截图如下图:

iShot2022-04-16_23.17.58.png

从官网下载和从JetBrains网页版插件市场找到的,都是最高只支持到191版本的插件,那么如何才能把Lombok插件装上呢?

其实吧,插件本身的功能没有任何问题,可以基本正常运行在AS 211版本,只是插件自带的允许使用的版本号范围只包含了191版本。因此我们直接把这个限制放开,然后正常安装就好了。

首先到JetBrains官方插件市场下载支持191版本的Lombok插件包,如下图:

iShot2022-04-19_10.25.20.png

使用WinRAR等压缩软件把下载到的插件.zip包解压,得到.jar文件,打开.jar文件,如下图:

把“META-INF”文件夹下的“plugin.xml”文件拖出,如下图:

iShot2022-04-16_23.19.38.png

使用文本编辑器打开,找到“idea-version",将“until-build”字段的值里面的“191.”改为“211.”,如下图:

iShot2022-04-16_23.20.01.png

保存后将“plugin.xml”拖回到.jar文件中,如下图:

iShot2022-04-16_23.20.50.png

然后打开AS的插件市场,进行离线安装,即可正常安装完成,如下图:

iShot2022-04-16_23.18.04.png

很久没有做Android开发了,最近上海遇到抢菜高峰,为了家里能有稳定的食物来源,我不得不使用重启这部分专业知识来完成一些小小的工作。

时隔几年之后,Android Studio(以下简称AS)也有了多个版本的升级,我照例把开发环境升级到最新版,版本信息如下:

Android Studio Bumblebee | 2021.1.1 Patch 3
Build #AI-211.7628.21.2111.8309675, built on March 17, 2022
Runtime version: 11.0.11+0-b60-7590822 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 10.15.7
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 16
Registry: external.system.auto.import.disabled=true
Non-Bundled Plugins: Lombook Plugin (0.34.1-2019.1), org.intellij.plugins.markdown (211.7142.37)

当我开发好之后想要推送代码到Github时,AS突然报了个错给我,如下图:

iShot2022-04-15_21.05.37.png

具体信息如下:

21:02:26.126: [food-grabber] git -c credential.helper= -c core.quotepath=false -c log.showSignature=false push --progress --porcelain origin refs/heads/master:master --set-upstream
Invocation failed Unexpected end of file from server
java.lang.RuntimeException: Invocation failed Unexpected end of file from server
    at org.jetbrains.git4idea.GitAppUtil.sendXmlRequest(GitAppUtil.java:30)
    at org.jetbrains.git4idea.http.GitAskPassApp.main(GitAskPassApp.java:58)
Caused by: java.net.SocketException: Unexpected end of file from server
    at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:866)
    at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:689)
    at java.base/sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:863)
    at java.base/sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:689)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1615)
    at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
    at org.apache.xmlrpc.DefaultXmlRpcTransport.sendXmlRpc(DefaultXmlRpcTransport.java:87)
    at org.apache.xmlrpc.XmlRpcClientWorker.execute(XmlRpcClientWorker.java:72)
    at org.apache.xmlrpc.XmlRpcClient.execute(XmlRpcClient.java:194)
    at org.apache.xmlrpc.XmlRpcClient.execute(XmlRpcClient.java:185)
    at org.apache.xmlrpc.XmlRpcClient.execute(XmlRpcClient.java:178)
    at org.jetbrains.git4idea.GitAppUtil.sendXmlRequest(GitAppUtil.java:27)
    ... 1 more
error: unable to read askpass response from '/Users/xxx/Library/Caches/Google/AndroidStudio2021.1/tmp/intellij-git-askpass-local.sh'
fatal: could not read Username for 'http://gitxxx.com': Device not configured

搜到的解决办法多数是让我到“.git”目录下修改“config”文件,把用户名和密码加到Git远程地址的URL中,如下,其中xxx是用户名,yyy是密码:

[remote "origin"]
url = http://xxx:yyy@github.com/aaa/bbb.git
fetch = +refs/heads/*:refs/remotes/origin/*

然而这个解决方法对我无效,多方查证无果,最后在一个国外网站上找到了相关的解决办法,只需勾选一个选项即可解决问题。如下图:

iShot2022-04-15_21.05.55.png

勾选之后再次提交,问题解决。

iShot2022-04-15_21.06.10.png

21:06:01.750: [food-grabber] git -c core.quotepath=false -c log.showSignature=false push --progress --porcelain origin refs/heads/master:master --set-upstream
Enumerating objects: 66, done.
Counting objects:   1% (1/66)
Counting objects: 100% (66/66), done.
Delta compression using up to 16 threads
Compressing objects:   1% (1/55)
Compressing objects: 100% (55/55), done.
Writing objects:   1% (1/66)
Writing objects: 100% (66/66), 136.46 KiB | 13.65 MiB/s, done.
Total 66 (delta 2), reused 0 (delta 0), pack-reused 0
To http://git.hotsun168.com/HomeApps/food-grabber.git
*    refs/heads/master:refs/heads/master    [new branch]
Branch 'master' set up to track remote branch 'master' from 'origin'.
Done

什么时候熊厂能够给点力???