准备
jdk
tomcat8
cfssl
# 安装java环境略
java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
curl -fksSL -O https://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.61/bin/apache-tomcat-8.5.61.tar.gz
tar -xvf apache-tomcat-8.5.61.tar.gz
for i in "cfssl" "cfssl-bundle" "cfssl-certinfo" "cfssl-newkey" "cfssl-scan" "cfssljson" "mkbundle" "multirootca"; do \
curl -sSL -o /usr/local/bin/${i} https://github.com/cloudflare/cfssl/releases/download/v1.5.0/${i}_1.5.0_linux_amd64; \
chmod +x /usr/local/bin/${i}; \
done
制作证书
cat > config.json <<EOF
{
"signing": {
"default": {
"expiry": "876000h"
},
"profiles": {
"kubernetes": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "876000h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "876000h"
}
}
}
}
EOF
cat > ca-csr.json <<EOF
{
"CN": "root-ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "dyrnq"
}
],
"ca": {
"expiry": "876000h"
}
}
EOF
cat > server-csr.json <<EOF
{
"CN": "tomcat",
"hosts": [
"127.0.0.1",
"192.168.1.101",
"tomcat",
"tomcat.default",
"tomcat.default.svc",
"tomcat.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "dyrnq"
}
]
}
EOF
cat > client-csr.json <<EOF
{
"CN": "client",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"O": "tomcat"
}
]
}
EOF
cat server-csr.json;
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=config.json -profile=kubernetes server-csr.json | cfssljson -bare server
在server-csr.json的hosts字段增加你的tomcat要使用的域名或者IP。
配置tomcat
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol" secure="true" scheme="https" SSLEnabled="true">
<SSLHostConfig caCertificateFile="ca.pem">
<Certificate
certificateFile="server.pem"
certificateKeyFile="server-key.pem" />
</SSLHostConfig>
</Connector>
启动tomcat
./catalina.sh run
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/java
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
23-Dec-2020 23:45:09.331 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/8.5.61
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Dec 3 2020 14:03:28 UTC
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version number: 8.5.61.0
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 4.19.95
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/java/jre
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_201-b09
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/tomcat
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/tomcat
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
23-Dec-2020 23:45:09.333 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
23-Dec-2020 23:45:09.334 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The Apache Tomcat Native library which allows using OpenSSL was not found on the java.library.path: [/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib]
23-Dec-2020 23:45:09.421 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
23-Dec-2020 23:45:09.429 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
23-Dec-2020 23:45:09.438 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio2-8443"]
23-Dec-2020 23:45:09.602 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 512 ms
23-Dec-2020 23:45:09.615 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
23-Dec-2020 23:45:09.615 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.61
23-Dec-2020 23:45:09.619 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/ROOT]
23-Dec-2020 23:45:09.743 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/ROOT] has finished in [124] ms
23-Dec-2020 23:45:09.743 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/docs]
23-Dec-2020 23:45:09.752 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/docs] has finished in [9] ms
23-Dec-2020 23:45:09.752 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/examples]
23-Dec-2020 23:45:09.882 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/examples] has finished in [129] ms
23-Dec-2020 23:45:09.882 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/host-manager]
23-Dec-2020 23:45:09.894 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/host-manager] has finished in [12] ms
23-Dec-2020 23:45:09.895 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/manager]
23-Dec-2020 23:45:09.905 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [11] ms
23-Dec-2020 23:45:09.910 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
23-Dec-2020 23:45:09.955 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["https-jsse-nio2-8443"]
23-Dec-2020 23:45:09.955 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 353 ms
我们用chrome浏览器打开 https://192.168.1.101:8443
,由于是自签的证书,chrome浏览器会提示 您的连接不是私密连接 攻击者可能会试图从 192.168.1.101 窃取您的信息(例如:密码、通讯内容或信用卡信息)。了解详情
,这时候我们点开
NET::ERR_CERT_AUTHORITY_INVALID高级
,点击 继续前往192.168.1.101(不安全)
即可。也可以用curl命令加上--cacert
进行测试。
curl --cacert ./ca.pem https://127.0.0.1:8443
curl --resolve "tomcat:8443:127.0.0.1" --cacert ./ca.pem https://tomcat:8443
也可以通过curl命令加上--insecure
强制忽略验证
curl --insecure https://127.0.0.1:8443
openssl s_client -showcerts -connect 127.0.0.1:8443 -servername 127.0.0.1:8443 </dev/null 2>/dev/null |openssl x509 -noout -text
通过以下命令得到sha1指纹
openssl s_client -showcerts -connect 127.0.0.1:8443 -servername 127.0.0.1:8443 </dev/null 2>/dev/null |openssl x509 -in /dev/stdin -sha1 -noout -fingerprint
双向认证
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=config.json -profile=client client-csr.json | cfssljson -bare client
keytool -importcert -trustcacerts \
-alias server-trust \
-file ca.pem -keystore server-trust.keystore \
-v \
-noprompt \
-storepass changeit
<Connector port="9443" protocol="org.apache.coyote.http11.Http11Nio2Protocol" secure="true" scheme="https" SSLEnabled="true">
<SSLHostConfig caCertificateFile="ca.pem" truststoreType="jks" truststoreFile="server-trust.keystore" truststorePassword="changeit" certificateVerification="required">
<Certificate
certificateFile="server.pem"
certificateKeyFile="server-key.pem" />
</SSLHostConfig>
</Connector>
这时候我们再用chrome浏览器打开https://192.168.1.101:9443
会提示报错:
此网站无法提供安全连接192.168.1.101 不接受您的登录证书,或者您可能没有提供登录证书。
请尝试联系系统管理员。
ERR_BAD_SSL_CLIENT_AUTH_CERT
使用curl命令也会报错alert bad certificate
curl --cacert ./ca.pem https://127.0.0.1:9443
curl: (35) error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
curl -k https://127.0.0.1:9443
curl: (35) error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
正确的方法用curl命令带--cacert
--cert
--key
这三个参数
curl --cacert ./ca.pem --cert client.pem --key client-key.pem https://127.0.0.1:9443
总结
tree -I "*.json|*.csr"
.
|-- ca-key.pem
|-- ca.pem
|-- client-key.pem
|-- client.pem
|-- server-key.pem
|-- server-trust.keystore
`-- server.pem
0 directories, 7 files
jks -> p12
keytool -importkeystore \
-srckeystore server-trust.keystore \
-srcstoretype JKS \
-deststoretype PKCS12 \
-destkeystore server-trust.p12 \
-srcalias server-trust \
-destalias server-trust \
-srcstorepass changeit \
-deststorepass changeit \
-noprompt \
-v
keytool -list -keystore ./server-trust.p12 -storepass changeit -v
Keystore type: PKCS12
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: server-trust
Creation date: Dec 25, 2020
Entry type: trustedCertEntry
keytool -list -keystore ./server-trust.keystore -storepass changeit -v
Keystore type: jks
Keystore provider: SUN
Your keystore contains 1 entry
Alias name: server-trust
Creation date: Dec 25, 2020
Entry type: trustedCertEntry
这里需要注意jdk版本default keystore type 是JKS还是PKCS12 https://openjdk.java.net/jeps/229
<Connector port="9443" protocol="org.apache.coyote.http11.Http11Nio2Protocol" secure="true" scheme="https" SSLEnabled="true">
<SSLHostConfig caCertificateFile="ca.pem" truststoreType="pkcs12" truststoreFile="server-trust.p12" truststorePassword="changeit" certificateVerification="required">
<Certificate
certificateFile="server.pem"
certificateKeyFile="server-key.pem" />
</SSLHostConfig>
</Connector>
ref
- https://tomcat.apache.org/tomcat-8.5-doc/ssl-howto.html
- https://tomcat.apache.org/tomcat-8.5-doc/config/http.html#SSL_Support_-_SSLHostConfig
- https://geekflare.com/tomcat-ssl-guide/
- https://geekflare.com/apache-tomcat-hardening-and-security-guide/
- https://blog.csdn.net/chuzhi78/article/details/76877935
- https://colobu.com/2016/06/07/simple-golang-tls-examples/
- https://yevon-cn.github.io/2017/04/09/https-config-of-tomcat.html
- https://blog.freessl.cn/ssl-cert-format-introduce/