I made it for the purpose of sending back bad HTTP headers, grammatically NG HTML, or grammatically NG JavaScript to the other party when checking the operation of the HTTPS client.
The environment is as follows.
I'll do it using openssl.
If I just wanted to SSL it, the method is described below (I used it as a reference. Thank you)
https://qiita.com/masakielastic/items/05cd6a36bb6fb10fccf6
https://stackoverflow.com/a/41366949/531320
For example, if you want to name the key mock.key and the certificate mock.crt: The domain is super suitable (because I don't use it ...)
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout mock.key -out mock.crt -subj "/CN=test.com" -days 3650
With this, if you write Python later, you can SSL.
I wrote it based on the code in the following article (I used it as a reference. Thank you)
https://qiita.com/butada/items/9450e39d8d4aac6ac1fe
The official documentation is below.
https://docs.python.org/3/library/ssl.html
And this is the code I wrote.
#!/usr/bin/env python
# coding: utf-8
import socket
import ssl
import sys
'''
Please do not hesitate to contact us depending on the environment.
'''
TEST_IP = '10.0.0.12'
TEST_PORT = 443
TEST_KEY = "mock.key"
TEST_CERT = "mock.crt"
class TestSSLServer:
'''
I tried to summarize the basic operation system of the SSL server roughly
'''
def init_soccket(self, key, cert, ip, port):
self.ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self.ssl_context.load_cert_chain(certfile=cert, keyfile=key)
self.bind_socket = socket.socket()
self.bind_socket.setsockopt(
socket.SOL_SOCKET,
socket.SO_REUSEADDR,
1)
self.bind_socket.setsockopt(
socket.SOL_SOCKET,
socket.SO_REUSEPORT,
1)
self.bind_socket.bind((ip, port))
self.bind_socket.listen(5) #Appropriate
def finsih_socket(self):
self.connection_stream.shutdown(socket.SHUT_RDWR)
self.connection_stream.close()
def accept_socket(self):
while True:
try:
self.accept_socket, _fromaddr = self.bind_socket.accept()
self.connection_stream = self.ssl_context.wrap_socket(
self.accept_socket, server_side=True)
return
except ssl.SSLError:
'''
Chrome,Firefox gives this error
Return to accept in preparation for connection
'''
print("wrap: SSL error:", sys.exc_info()[0])
continue
except OSError:
'''
Safari system gives this error
Return to accept in preparation for connection
'''
print("wrap: OS error:", sys.exc_info()[0])
continue
except BaseException:
'''
I don't know anything else, so I'll assume that the process didn't end w (CTRL)-C should come here)
'''
print(
"wrap: Unexpected error:",
sys.exc_info()[0])
sys.exit(1)
def read_stream(self):
bin_data = self.connection_stream.read()
return bin_data
def write_stream(self, bin_data):
self.connection_stream.sendall(bin_data)
if __name__ == '__main__':
'''
Initialization
'''
server = TestSSLServer()
server.init_soccket(TEST_KEY, TEST_CERT, TEST_IP, TEST_PORT)
'''
Waiting for connection
'''
server.accept_socket()
'''
Request and response once
'''
bin_data = server.read_stream()
if bin_data:
print (bin_data)
content = "<html>test</html>"
text = "HTTP/1.1 200 OK\r\n"
text += "Content-Length: " + str(len(content)) + "\r\n\r\n"
text += content
server.write_stream(text.encode())
'''
Disconnect, release resources
'''
server.finsih_socket()
The original code was Python2, but I am trying to make it work with 3. Also, SO_REUSEADDR is set in consideration of the case when it is stopped in the middle.
After that, the behavior at the time of error is changed so that it is OK even if it is accessed from the browser. Specifically, if authentication fails due to me, ssl.SSLError or OSError will be displayed, so in that case, just start over from accept w
As you can see from the code, you have to write all the headers and bodies yourself. In other words, you can look back at your favorite data without worrying about grammar.
As for the execution method, when using port 443, it was necessary to sudo on Ubuntu. Something like this.
sudo python3.7 sample_server.py
The rest is from the browser
https://xxx.xxxx.xxxx.xxx:nnnn
You can access it like that. If TEST_PORT is set to 443,: nnnn is unnecessary. I'm sure you'll be scolded for the certificate, but if you know it and do it in the flow of connection, you should get test.
Recommended Posts