TLS LAB
Task 1: TLS Client
Task 1.a: TLS handshake
#开启容器
dcup
容器中有三个机器,一个用于客户端,一个用于服务器,另一个用于代理,IP地址如下
client: 10.9.0.5
server: 10.9.0.43
proxy: 10.9.0.143
进入容器的Client,与百度(www.baidu.com)进行通信
python3 handshake.py www.baidu.com
- Question
-
What is the cipher used between the client and the server?
从下面可以看出使用的加密算法
使用AES128-GCM算法进行加密通信
参数意义如下
-
Please print out the server certifificate in the program.
-
Explain the purpose of /etc/ssl/certs.
该目录用来存储根CA证书,验证服务器发回来的证书的有效性 -
Use Wireshark to capture the network traffifics during the execution of the program, and explain yourobservation. In particular, explain which step triggers the TCP handshake, and which step triggers theTLS handshake. Explain the relationship between the TLS handshake and the TCP handshake.
tcp三握手
由客户端向服务器发送SYN数据包开始建立tcp连接
TLS握手
由客户端向服务器发送Client Hello数据包开始建立TLS连接
-
Task 1.b: CA’s Certifificate
修改Py文件
python3 handshake.py www.zhihu.com
无法使用本地的CA证书进行验证,建立TLS连接失败
查找根CA证书
在/etc/ssl/certs中查找证书
将对应证书拷贝到clien-certs目录下
cp /etc/ssl/certs/DigiCert_Global_Root_CA.pem /volumes/client-certs
生成哈希值并链接
成功建立SSL连接
Task 1.c: Experiment with the hostname check
执行dig命令
context.check_hostname = True时
无法建立连接
context.check_hostname = False时
成功建立连接
Task 1.d: Sending and getting Data
发送HTTP请求,并接收数据。
修改代码后运行
handshake.py www.baidu.com
成功接收到http请求
![[Pasted image 20220811202345.png]]
Task 2: TLS Server
Task 1.a: TLS handshake
在client中添加DNS记录
利用PKI实验中的CA为server签名
#生成key和csr
openssl req -newkey rsa:2048 -sha256 \
-keyout server.key -out server.csr \
-subj "/CN=www.hyl2022.com/O=hyl57119419 Inc./C=CN" \
-passout pass:dees \
-addext "subjectAltName = DNS:www.hyl2022.com"
# 生成crt
openssl ca -config myCA_openssl.cnf -policy policy_anything -md sha256 -days 3650 -in server.csr -out server.crt -batch -cert ca.crt -keyfile ca.key
将生成的server.key和server.crt放在server-certs文件夹中
将ca.crt放入client-certs中,并使用openssl命令获取hash之后在client-certs中建立软链接
修改server.py(文件地址和端口号)
在server端运行server.py文件
在client端添加地址映射后访问www.hyl2022.com
server端也有输出:
将handshake.py中的certs目录修改为/etc/ssl/certs后无法建立ssl连接
Task 2.b. Testing the server program using browsers
在浏览器中加入ca.crt证书
about:preferences#privacy
在/etc/hosts中添加地址映射
在浏览器访问域名
Task 2.c. Certifificate with multiple names
配置cnf
[ req ]
prompt = no
distinguished_name = req_distinguished_name
req_extensions = req_ext
[ req_distinguished_name ]
C = CN
ST = Jiangsu
L = Nanjing
O = Seu
CN = www.hyl2022.com
[ req_ext ]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.hyl2022.com
DNS.2 = www.hyl2022.net
DNS.3 = *.hyl2022.com
生成CSR
openssl req -newkey rsa:2048 -config ./server_openssl.cnf -batch -sha256 -keyout server2.key -out server2.csr
生成crt
openssl ca -md sha256 -days 3650 -config ./myCA_openssl.cnf -batch -in server2.csr -out server2.crt -cert ca.crt -keyfile ca.key
将生成的server.key和server.crt放在server-certs文件夹中
修改server.py后开启服务器
在client端添加地址映射
访问www.hyl2022.net和www.hyl2022.com(均访问成功)
![[Pasted image 20220814111724.png]]
Task 3: A Simple HTTPS Proxy
选择网站www.zhihu.com,并为其签发证书
openssl req -newkey rsa:2048 -sha256 \
-keyout zhihu.key -out zhihu.csr \
-subj "/CN=www.zhihu.com/O=hyl Inc./C=CN" \
-passout pass:dees
openssl ca -config myCA_openssl.cnf -policy policy_anything -md sha256 -days 3650 -in zhihu.csr -out zhihu.crt -batch -cert ca.crt -keyfile ca.key
编写proxy.py放入volumes文件夹
#!/usr/bin/env python3
import threading
import ssl
import socket
cadir = "/etc/ssl/certs"
def process_request(ssock_for_browser):
hostname = "www.zhihu.com"
# Make a connection to the real server
sock_for_server = socket.create_connection((hostname, 443))
# Set up the TLS context
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations(capath=cadir)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
print("sock_for_server")
ssock_for_server = context.wrap_socket(sock_for_server, server_hostname=hostname, do_handshake_on_connect=False)
ssock_for_server.do_handshake()
request = ssock_for_browser.recv(2048)
if request:
# Forward request to server
ssock_for_server.sendall(request)
# Get response from server, and forward it to browser
response = ssock_for_server.recv(2048)
while response:
ssock_for_browser.sendall(response) # Forward to browser
response = ssock_for_server.recv(2048)
ssock_for_browser.shutdown(socket.SHUT_RDWR)
ssock_for_browser.close()
SERVER_CERT = "./zhihu.crt"
SERVER_PRIVATE = "./zhihu.key"
context_srv = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context_srv.load_cert_chain(SERVER_CERT, SERVER_PRIVATE)
sock_listen = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
sock_listen.bind(("0.0.0.0", 443))
sock_listen.listen(5)
while True:
sock_for_browser, fromaddr = sock_listen.accept()
print(fromaddr)
ssock_for_browser = context_srv.wrap_socket(sock_for_browser, server_side=True)
x = threading.Thread(target=process_request, args=(ssock_for_browser,))
x.start()
修改地址映射
修改proxy端的/etc/resolv.cnf,将nameserver修改为8.8.8.8
在宿主中访问www.zhihu.com